package logic

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gogap/logs"
	"github.com/shopspring/decimal"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"log"
	"sort"
	"strconv"
	"strings"
	"time"
	"yundian/internel/app/dao"
	"yundian/internel/app/dao/memberdao"
	"yundian/internel/app/helper"
	"yundian/internel/app/helper/request"
	"yundian/internel/app/helper/resphelper"
	"yundian/internel/app/helper/resphelper/placeresp"
	"yundian/internel/app/models/agentincome"
	"yundian/internel/app/models/automate"
	"yundian/internel/app/models/cashlog"
	"yundian/internel/app/models/complaintslog"
	"yundian/internel/app/models/coupon"
	"yundian/internel/app/models/couponinfo"
	"yundian/internel/app/models/couponlog"
	"yundian/internel/app/models/devices"
	"yundian/internel/app/models/dividendslog"
	"yundian/internel/app/models/membermodel"
	"yundian/internel/app/models/orders"
	"yundian/internel/app/models/paysetting"
	"yundian/internel/app/models/placeincome"
	"yundian/internel/app/models/prices"
	"yundian/internel/app/models/users"
	"yundian/internel/app/models/wifimodel"
	"yundian/internel/app/models/withdrawalsetting"
	"yundian/internel/pkg/dbs"
	"yundian/internel/pkg/dingo"
	"yundian/internel/pkg/dingo/global"
	"yundian/internel/pkg/utils"
	"yundian/internel/pkg/wechatpay"
	"yundian/internel/pkg/wxpay"
)

type OrderLogic struct {
	TradeNo   string
	PayClient *wxpay.PayClient
	WxConfig  *paysetting.PaySetting
}

func NewOrderLogic() *OrderLogic {
	tradeNo := utils.Join(global.Const.Pre.OrderPre, time.Now().Format("20060102150405"), utils.GetRandomInt(6))
	payClient := wxpay.NewPayClient(nil)
	wxConfig := NewSettingLogic().GetPaySetting()
	return &OrderLogic{PayClient: payClient, TradeNo: tradeNo, WxConfig: wxConfig}
}

// ------------------------------ 统一下订单(押金支付) ------------------------------//

// HandleWxStewardGetAgainOrder 重新下单
func (logic *OrderLogic) HandleWxStewardGetAgainOrder(tradeNo string) (pay string) {
	return global.Rdb.Get(context.Background(), fmt.Sprintf("trade_no%s", tradeNo)).Val()
}

// HandleWxStewardSetAgainOrder 记录下单
func (logic *OrderLogic) HandleWxStewardSetAgainOrder(tradeNo string, pay string) error {
	db := global.Rdb.Set(context.Background(), fmt.Sprintf("trade_no%s", tradeNo), pay, time.Minute*5)
	return db.Err()
}

// HandleWxStewardUnifiedOrder 统一下订单业务逻辑
func (logic *OrderLogic) HandleWxStewardUnifiedOrder(param *request.CreateStewardOrderReq) (respData *wxpay.PayData, err error) {
	apiData := logic.GenerateWxStewardUnifiedOrderApiParamV2(param)
	log.Println("HandleWxStewardUnifiedOrder,    生成的apiData", &apiData)
	respData, err = wxpay.ApiUnifiedOrder(logic.PayClient, apiData, logic.WxConfig) // 请求微信API
	log.Println("HandleWxStewardUnifiedOrder ", &respData)
	return
}

type Amount struct {
	Refund   int64  `json:"refund"`
	Total    int64  `json:"total"`
	Currency string `json:"currency"`
}

// GenerateWxStewardUnifiedOrderApiParamV2  统一下单 -- 使用 V2
func (logic *OrderLogic) GenerateWxStewardUnifiedOrderApiParamV2(param *request.CreateStewardOrderReq) *wxpay.PayData {
	body := global.Const.Desc.UnifiedBody
	if param.RoomTypeId > 0 {
		body = global.Const.Desc.UnifiedRoomBody
	}
	if len(param.GoodsList) > 0 {
		body = global.Const.Desc.UnifiedGoodsBody
	}
	if param.RoutesId > 0 {
		body = global.Const.Desc.UnifiedAutomateBody
	}
	if param.TicketId > 0 {
		body = "景点旅游预定"
	}

	apiData := wxpay.NewPayData()
	apiData.Set("openid", param.Openid)                                  // openid
	apiData.Set("device_info", param.DeviceSn)                           // 设备标识
	apiData.Set("body", body)                                            // 订单内容
	apiData.Set("total_fee", param.Amount)                               // 支付金额
	apiData.Set("detail", global.Const.Desc.UnifiedDetail)               // 订单详情
	apiData.Set("fee_type", global.Const.Desc.FeeType)                   // 币种
	apiData.Set("trade_type", wxpay.TradeTypeJsApi)                      // 交易类型  JSAPI
	apiData.Set("out_trade_no", logic.TradeNo)                           // 订单编号
	apiData.Set("spbill_create_ip", param.ClientIp)                      // 客户端IP
	apiData.Set("notify_url", logic.WxConfig.DepositNotifyUrl+param.Key) // 微信通知服务器的url
	apiData.Set("time_start", wxpay.FormatTime(time.Now()))              // 订单开始时间
	// 订单过期时间
	apiData.Set("time_expire", wxpay.FormatTime(time.Now().Add(time.Minute*10)))
	apiData.Set("nonce_str", wxpay.NonceStr()) // 随机字符串
	apiData.Set("attach", param.Key)

	return apiData
}

// HandleWxUnifiedOrder 统一下订单业务逻辑
func (logic *OrderLogic) HandleWxUnifiedOrder(param *request.CreateOrderReq) (respData *wxpay.PayData, err error) {
	apiData := logic.GenerateWxUnifiedOrderApiParamV2(param)
	//log.Println("统一下订单,    生成的apiData")
	respData, err = wxpay.ApiUnifiedOrder(logic.PayClient, apiData, logic.WxConfig) // 请求微信API
	//log.Println("统一下订单返回结果 ", respData)
	return
}

// HandleMakeSign 二次签名
func (logic *OrderLogic) HandleMakeSign(respData *wxpay.PayData) *wxpay.PayData {

	timeStamp := wxpay.TimeStamp()
	nonceStr := wxpay.NonceStr()
	packageStr := "prepay_id=" + respData.Get("prepay_id")

	resultData := wxpay.NewPayData()
	resultData.Set("appId", logic.WxConfig.AppId)
	resultData.Set("timeStamp", timeStamp)
	resultData.Set("nonceStr", nonceStr)
	resultData.Set("package", packageStr)
	resultData.Set("signType", wxpay.SignTypeMD5)

	paySign := resultData.MakeSign(logic.WxConfig.ApiKey, wxpay.SignTypeMD5)

	resultData.Set("errcode", 100200)
	resultData.Set("errmsg", wxpay.RCSuccess)
	resultData.Set("paySign", paySign)
	resultData.Set("tradeNo", logic.TradeNo)

	return resultData
}

// GetDeviceMoney 获取设备价格
func (logic *OrderLogic) GetDeviceMoney(param *request.CreateOrderReq) int64 {

	ruleInfo := dao.NewPricesDao().GetPriceDetail(param.ProductId).Unwrap().(*prices.PriceModel)

	var money int64 // 单位-分
	//if helper.IsSetMeal(param.DeviceModelId) {
	//	money = ruleInfo.Deposit // 支付押金  // 单套餐
	//} else {
	//	money = ruleInfo.PayMoney // 支付套餐价
	//}

	if param.FeeMode == 1 { // 计时模式
		money = ruleInfo.Deposit // 支付押金  // 单套餐
	} else {
		money = ruleInfo.PayMoney // 支付套餐价
	}

	//// 判断是否有优惠券
	//isCouponInfo, rowsAffected := dao.NewCouponDao().GetCouponInfo(param.UserId)
	//if rowsAffected > 0 {
	//	//修改金额
	//
	//	couponInfoModel := isCouponInfo.Unwrap().(*couponinfo.CouponInfo)
	//	couponData := dao.NewCouponDao().GetCoupon(couponInfoModel.CId).Unwrap().(*coupon.Coupon)
	//	money = money - int64(couponData.Discounts)
	//
	//	//修改优惠券状态
	//
	//	//添加优惠券日志
	//
	//}

	if money < 0 {
		money = 0
	}

	return money
}

// GenerateWxUnifiedOrder 统一下单 -- 使用 V2
func (logic *OrderLogic) GenerateWxUnifiedOrderApiParamV2(param *request.CreateOrderReq) *wxpay.PayData {

	apiData := wxpay.NewPayData()
	apiData.Set("openid", param.Openid)                        // openid
	apiData.Set("device_info", param.DeviceSn)                 // 设备标识
	apiData.Set("body", global.Const.Desc.UnifiedBody)         // 订单内容
	apiData.Set("total_fee", logic.GetDeviceMoney(param))      // 支付金额
	apiData.Set("detail", global.Const.Desc.UnifiedDetail)     // 订单详情
	apiData.Set("fee_type", global.Const.Desc.FeeType)         // 币种
	apiData.Set("trade_type", wxpay.TradeTypeJsApi)            // 交易类型  JSAPI
	apiData.Set("out_trade_no", logic.TradeNo)                 // 订单编号
	apiData.Set("spbill_create_ip", param.ClientIp)            // 客户端IP
	apiData.Set("notify_url", logic.WxConfig.DepositNotifyUrl) // 微信通知服务器的url
	apiData.Set("time_start", wxpay.FormatTime(time.Now()))    // 订单开始时间
	// 订单过期时间
	apiData.Set("time_expire", wxpay.FormatTime(time.Now().Add(time.Minute*10)))
	apiData.Set("nonce_str", wxpay.NonceStr()) // 随机字符串
	apiData.Set("attach", param.ProductId)

	return apiData
}

// -------------------------------- 结束订单 --------------------------------- //

// HandleWxEndOrderByAdmin 订单结束业务逻辑 -- 后台完结订单使用
//func (logic *OrderLogic) HandleWxEndOrderByAdmin(param *request.CloseOrderReq) (*wechatpay.PayData, error) {
//	var settResult *resphelper.SettlementResp
//	var wc *paysetting.PaySetting
//	devInfo := dao.NewDeviceDao().FetchDeviceInfoWithType(param.DeviceSn).Unwrap().(*devices.DeviceType)
//	ruleInfo := dao.NewPricesDao().GetPriceDetail(param.ProductId).Unwrap().(*prices.PriceModel)
//	orderInfo := dao.NewOrderDao().GetOrderInfoByTradeNo(param.TradeNo).Unwrap().(*orders.OrderModel)
//
//	if orderInfo.Appid != "" {
//		wc = NewSettingLogic().GetPaySettingByAppid(orderInfo.Appid)
//	} else {
//		wc = logic.WxConfig
//	}
//
//	var useTime, settMoney, returnMoney int64
//	// 计算订单结算金额
//	if orderInfo.FeeMode == 1 { // 计时模式
//		settResult = logic.GetOrderSettMoney(
//			int64(orderInfo.PayAt),
//			param.EndTime,
//			orderInfo.PayMoney,
//			ruleInfo,
//			orderInfo.PayFrom,
//		)
//	} else { // feeMode == 2 套餐模式
//		useTime = param.EndTime - int64(orderInfo.PayAt)
//		//if useTime > int64(ruleInfo.UseDuration) {
//		//	settMoney = ruleInfo.PayMoney
//		//} else {
//		//	settMoney = ruleInfo.PayMoney
//		//}
//		settMoney = ruleInfo.PayMoney
//		returnMoney = 0
//		if orderInfo.PayMoney > ruleInfo.PayMoney { // 支付的金额大于套餐用时最大金额
//			returnMoney = orderInfo.PayMoney - ruleInfo.PayMoney
//		}
//		settResult = &resphelper.SettlementResp{
//			UseTime:     useTime,
//			SettMoney:   settMoney,
//			ReturnMoney: returnMoney,
//		}
//	}
//
//	log.Println("打印结算结果 使用时长、结算金额、应退还金额", settResult) //
//
//	//使用优惠券
//	isCouponInfo, rowsAffected := dao.NewCouponDao().GetByOpenIdCouponInfo(orderInfo.Openid)
//	if rowsAffected > 0 {
//		//修改金额
//		couponInfoModel := isCouponInfo.Unwrap().(*couponinfo.CouponInfo)
//		couponData := dao.NewCouponDao().GetCoupon(couponInfoModel.CId).Unwrap().(*coupon.Coupon)
//		settResult.SettMoney = settResult.SettMoney - int64(couponData.Discounts)
//		if settResult.SettMoney < 0 {
//			settResult.SettMoney = 0
//		}
//		log.Println("打印结算结果 使用时长、结算金额、应退还金额", settResult)
//	}
//
//	if settResult.ReturnMoney > 0 { // 退款 - 异步退款
//		apiData := logic.HandleRefundApiParamV2(
//			orderInfo.Money,
//			settResult.ReturnMoney,
//			orderInfo.OutTradeNo,
//			"结束订单", wc.RefundNotifyUrl)
//		logic.HandleRefund(apiData, wc)
//		//dingo.Task(logic.HandleRefund, func() {}, apiData)
//
//		// 验证退款成功后再执行
//		//dingo.Task(logic.CalOrderDividends, func() {}, orderInfo, devInfo, settResult.SettMoney) // 计算分红 - 异步任务
//		dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime) // 修改订单状态 - 异步任务
//	} else { // 完结订单
//		if orderInfo.PayFrom == 1 { // 免押支付
//			// 先查询订单
//			queryData, err := wechatpay.ApiQueryPayScoreOrder(param.TradeNo, wc) // 查询微信订单
//			if err != nil {
//				log.Println("微信订单查询失败")
//			}
//			if queryData != nil && queryData.Get("state") == "DOING" && queryData.Get("state_description") == "USER_CONFIRM" {
//				apiData := NewWxOrderLogic().OrderCompleteApiData(settResult.SettMoney, ruleInfo, orderInfo.PlaceName, devInfo.FeeMode)
//				//respData,err := wechatpay.ApiCompletePayScoreOrder(apiData, param.TradeNo)
//				respData, err := wechatpay.ApiCompletePayScoreOrder(apiData, param.TradeNo, wc)
//				if err != nil {
//					log.Println("完结订单失败")
//				}
//				//if settResult.SettMoney == 0 {
//				//	logic.CouponPayScoreNotify(orderInfo, ruleInfo)
//				//}
//				log.Println("打印测试完结订单返回值", respData)
//				return respData, err
//			}
//		} else { // 押金
//			logic.CalOrderDividends(orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime))
//			//dingo.Task(logic.CalOrderDividends, func() {}, orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime)) // 押金支付的分红
//			dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime) // 修改订单状态 - 异步任务
//		}
//	}
//	dingo.Task(logic.UpdateDeviceInfo, func() {}, devInfo.DeviceSn) // 修改设备信息 - 异步任务
//	dingo.Task(logic.ClearRedisKey, func() {}, orderInfo.TradeNo)   // 清除 redis Key - 异步任务
//	return nil, nil
//
//}

// 押金模式结束订单
func (logic *OrderLogic) HandleWxEndOrderDeposit(param *request.CloseOrderReq) *resphelper.SettlementResp {

	var settResult *resphelper.SettlementResp
	devInfo := dao.NewDeviceDao().FetchDeviceInfoWithType(param.DeviceSn).Unwrap().(*devices.DeviceType)    // 设备信息
	ruleInfo := dao.NewPricesDao().GetLimitPriceDetail(param.ProductId).Unwrap().(*prices.PriceModel)    // 设备价格
	orderInfo := dao.NewOrderDao().GetLimitOneOrderInfoByTradeNo(param.TradeNo).Unwrap().(*orders.OrderModel) // 订单信息

	var useTime, settMoney, returnMoney, reduceTime, reduceMoney int64

	// 判断该用户是否有优惠券
	isCouponInfo, rowsAffected := dao.NewCouponDao().GetByOpenIdAndTradeNoCouponInfo(orderInfo.Openid, orderInfo.TradeNo)
	couponInfoModel := isCouponInfo.Unwrap().(*couponinfo.CouponInfo)
	if rowsAffected > 0 {
		switch couponInfoModel.Type {
		case 1: // 满减
		case 2: // 折扣
		case 3: // 现金
			reduceMoney = int64(couponInfoModel.Discounts)
		case 4: // 免费时长减免
			reduceTime = int64(couponInfoModel.Discounts)
		}
	}

	if orderInfo.FeeMode == 1 { // 计时模式
		settResult = logic.GetOrderSettMoney(
			int64(orderInfo.BeginAt),
			param.EndTime,
			orderInfo.PayMoney,
			ruleInfo,
			orderInfo.PayFrom,
			reduceTime,
		)
	} else { // feeMode == 2 套餐模式
		useTime = param.EndTime - int64(orderInfo.PayAt)
		settMoney = ruleInfo.PayMoney
		returnMoney = 0
		if orderInfo.PayMoney > ruleInfo.PayMoney { // 支付的金额大于套餐用时最大金额
			returnMoney = orderInfo.PayMoney - ruleInfo.PayMoney
		}
		settResult = &resphelper.SettlementResp{
			UseTime:     useTime,
			SettMoney:   settMoney,
			ReturnMoney: returnMoney,
		}
	}
	if reduceMoney > 0 {
		if settResult.SettMoney < reduceMoney {
			reduceMoney = settResult.SettMoney
		}
		settResult.ReduceMoney = reduceMoney
		settResult.CouponType = int8(couponInfoModel.Type)
		settResult.SettMoney = settResult.SettMoney - reduceMoney
	}

	//最低支付金额低于优惠券这里就变负数导致不能正常结束,将结算金额改为0
	if settResult.SettMoney < 0 {
		settResult.SettMoney = 0
	}

	log.Println("打印结算结果 使用时长、结算金额、应退还金额", settResult) //
	settResult.ReturnMoney += reduceMoney

	logic.CalOrderDividends(orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime))
	logic.UpdateOrderInfo(orderInfo.Id, settResult, param.EndTime)
	logic.UpdateDeviceInfo(orderInfo.DeviceSn)
	logic.ClearRedisKey(orderInfo.TradeNo)

	return settResult
}

// HandleWxEndOrder 订单结束业务逻辑
func (logic *OrderLogic) HandleWxEndOrder(param *request.CloseOrderReq) *resphelper.SettlementResp {

	var settResult *resphelper.SettlementResp
	var wc *paysetting.PaySetting
	devInfo := dao.NewDeviceDao().FetchDeviceInfoWithType(param.DeviceSn).Unwrap().(*devices.DeviceType)      // 设备信息
	ruleInfo := dao.NewPricesDao().GetLimitPriceDetail(param.ProductId).Unwrap().(*prices.PriceModel)         // 设备价格
	orderInfo := dao.NewOrderDao().GetLimitOneOrderInfoByTradeNo(param.TradeNo).Unwrap().(*orders.OrderModel) // 订单信息

	// 获取支付配置
	if orderInfo.Appid != "" {
		wc = NewSettingLogic().GetPaySettingByAppidAndMchid(orderInfo.Appid, orderInfo.Mchid)
	} else {
		wc = logic.WxConfig
	}

	var useTime, settMoney, returnMoney, reduceTime, reduceMoney int64

	// 判断该用户是否有优惠券
	isCouponInfo, rowsAffected := dao.NewCouponDao().GetByOpenIdAndTradeNoCouponInfo(orderInfo.Openid, orderInfo.TradeNo)
	couponInfoModel := isCouponInfo.Unwrap().(*couponinfo.CouponInfo)
	if rowsAffected > 0 {
		//couponData := dao.NewCouponDao().GetCoupon(couponInfoModel.CId).Unwrap().(*coupon.Coupon)
		switch couponInfoModel.Type {
		case 1: // 满减
		case 2: // 折扣
		case 3: // 现金
			reduceMoney = int64(couponInfoModel.Discounts)
		case 4: // 免费时长减免
			reduceTime = int64(couponInfoModel.Discounts)
		}
	}

	if orderInfo.FeeMode == 1 { // 计时模式
		settResult = logic.GetOrderSettMoney(
			int64(orderInfo.BeginAt),
			param.EndTime,
			orderInfo.PayMoney,
			ruleInfo,
			orderInfo.PayFrom,
			reduceTime,
		)
	} else { // feeMode == 2 套餐模式
		useTime = param.EndTime - int64(orderInfo.PayAt)
		settMoney = ruleInfo.PayMoney
		returnMoney = 0
		if orderInfo.PayMoney > ruleInfo.PayMoney { // 支付的金额大于套餐用时最大金额
			returnMoney = orderInfo.PayMoney - ruleInfo.PayMoney
		}
		settResult = &resphelper.SettlementResp{
			UseTime:     useTime,
			SettMoney:   settMoney,
			ReturnMoney: returnMoney,
		}
	}
	if reduceMoney > 0 {
		if settResult.SettMoney < reduceMoney {
			reduceMoney = settResult.SettMoney
		}
		settResult.ReduceMoney = reduceMoney
		settResult.CouponType = int8(couponInfoModel.Type)
		settResult.SettMoney = settResult.SettMoney - reduceMoney
	}

	//最低支付金额低于优惠券这里就变负数导致不能正常结束,将结算金额改为0
	if settResult.SettMoney < 0 {
		settResult.SettMoney = 0
	}

	log.Println("打印结算结果 使用时长、结算金额、应退还金额", settResult) //

	settResult.ReturnMoney += reduceMoney
	if settResult.ReturnMoney > 0 && orderInfo.PayFrom != 1 { // 押金退款
		apiData := logic.HandleRefundApiParamV2(
			orderInfo.Money,
			settResult.ReturnMoney,
			orderInfo.OutTradeNo,
			"结束订单", wc.RefundNotifyUrl)
		logic.HandleRefund(apiData, wc)

		logic.CalOrderDividends(orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime))
		//dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime) // 修改订单状态 - 异步任务
		if settResult.ReduceMoney == 0 {
			settResult.ReduceMoney = reduceTime
		}
		logic.UpdateOrderInfo(orderInfo.Id, settResult, param.EndTime)
		couponInfoModel.Status = 2
		couponInfoModel.OrderId = orderInfo.TradeNo
		dao.NewCouponDao().CouponInfoEditDao(couponInfoModel, int(settResult.SettMoney)) // 修改优惠券状态 - 异步任务
	} else { // 完结订单
		if orderInfo.PayFrom == 1 { // 免押支付
			// 先查询订单
			queryData, err := wechatpay.ApiQueryPayScoreOrder(param.TradeNo, wc) // 查询微信订单
			if err != nil {
				log.Println("微信订单查询失败")
			}
			if queryData != nil && queryData.Get("state") == "DOING" && queryData.Get("state_description") == "USER_CONFIRM" {
				// USER_CONFIRM 用户确认
				apiData := NewWxOrderLogic().OrderCompleteApiData(settResult.SettMoney, ruleInfo, orderInfo.PlaceName, uint8(orderInfo.FeeMode), queryData.Get("location"), wc)
				respData, err := wechatpay.ApiCompletePayScoreOrder(apiData, param.TradeNo, wc)
				if err != nil {
					log.Println("完结订单失败")
				}
				log.Println("打印测试完结订单返回值", respData)
			}
		} else { // 套餐支付
			logic.CalOrderDividends(orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime))
			dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime) // 修改订单状态 - 异步任务
		}
	}
	dingo.Task(logic.UpdateDeviceInfo, func() {}, orderInfo.DeviceSn) // 修改设备信息 - 异步任务
	dingo.Task(logic.ClearRedisKey, func() {}, orderInfo.TradeNo)     // 清除 redis Key - 异步任务
	return settResult
}

func (logic *OrderLogic) HandleWxEndOrderV3(param *request.CloseOrderReq, userId int) *resphelper.SettlementResp {

	var settResult *resphelper.SettlementResp
	var wc *paysetting.PaySetting
	devInfo := dao.NewDeviceDao().FetchDeviceInfoWithType(param.DeviceSn).Unwrap().(*devices.DeviceType)      // 设备信息
	ruleInfo := dao.NewPricesDao().GetLimitPriceDetail(param.ProductId).Unwrap().(*prices.PriceModel)         // 设备价格
	orderInfo := dao.NewOrderDao().GetLimitOneOrderInfoByTradeNo(param.TradeNo).Unwrap().(*orders.OrderModel) // 订单信息
	//placeInfo := dao.NewPlaceDao().GetPlaceById(orderInfo.PlaceId).Unwrap().(*placemodel.PlaceModel)          // 订单信息
	//memberInfo := memberdao.NewMemberDao().GetMemberInfoByOpenidAndAppId(orderInfo.Openid, orderInfo.Appid).Unwrap().(*membermodel.MembersModel)

	// 获取支付配置
	if orderInfo.Appid != "" {
		wc = NewSettingLogic().GetPaySettingByAppidAndMchid(orderInfo.Appid, orderInfo.Mchid)
	} else {
		wc = logic.WxConfig
	}

	var useTime, settMoney, returnMoney, reduceTime, reduceMoney int64

	// 判断该用户是否有优惠券
	isCouponInfo, rowsAffected := dao.NewCouponDao().GetByOpenIdAndTradeNoCouponInfo(orderInfo.Openid, orderInfo.TradeNo)
	couponInfoModel := isCouponInfo.Unwrap().(*couponinfo.CouponInfo)
	if rowsAffected > 0 {
		//couponData := dao.NewCouponDao().GetCoupon(couponInfoModel.CId).Unwrap().(*coupon.Coupon)
		switch couponInfoModel.Type {
		case 1: // 满减
		case 2: // 折扣
		case 3: // 现金
			reduceMoney = int64(couponInfoModel.Discounts)
		case 4: // 免费时长减免
			reduceTime = int64(couponInfoModel.Discounts)
		}
	}

	if orderInfo.FeeMode == 1 { // 计时模式
		settResult = logic.GetOrderSettMoney(
			int64(orderInfo.BeginAt),
			param.EndTime,
			orderInfo.PayMoney,
			ruleInfo,
			orderInfo.PayFrom,
			reduceTime,
		)
	} else { // feeMode == 2 套餐模式
		useTime = param.EndTime - int64(orderInfo.PayAt)
		settMoney = ruleInfo.PayMoney
		returnMoney = 0
		if orderInfo.PayMoney > ruleInfo.PayMoney { // 支付的金额大于套餐用时最大金额
			returnMoney = orderInfo.PayMoney - ruleInfo.PayMoney
		}
		settResult = &resphelper.SettlementResp{
			UseTime:     useTime,
			SettMoney:   settMoney,
			ReturnMoney: returnMoney,
		}
	}
	if reduceMoney > 0 {
		if settResult.SettMoney < reduceMoney {
			reduceMoney = settResult.SettMoney
		}
		settResult.ReduceMoney = reduceMoney
		settResult.CouponType = int8(couponInfoModel.Type)
		settResult.SettMoney = settResult.SettMoney - reduceMoney
	}

	//最低支付金额低于优惠券这里就变负数导致不能正常结束,将结算金额改为0
	if settResult.SettMoney < 0 {
		settResult.SettMoney = 0
	}

	log.Println("打印结算结果 使用时长、结算金额、应退还金额", settResult) //

	settResult.ReturnMoney += reduceMoney
	if settResult.ReturnMoney > 0 {
		apiData := logic.HandleRefundApiParamV2(
			orderInfo.Money,
			settResult.ReturnMoney,
			orderInfo.OutTradeNo,
			"结束订单", wc.RefundNotifyUrl)
		logic.HandleRefund(apiData, wc)

		logic.CalOrderDividends(orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime))
		//dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime) // 修改订单状态 - 异步任务
		if settResult.ReduceMoney == 0 {
			settResult.ReduceMoney = reduceTime
		}
		logic.UpdateOrderInfo(orderInfo.Id, settResult, param.EndTime)
		couponInfoModel.Status = 2
		couponInfoModel.OrderId = orderInfo.TradeNo
		dao.NewCouponDao().CouponInfoEditDao(couponInfoModel, int(settResult.SettMoney)) // 修改优惠券状态 - 异步任务
	} else {
		logic.CalOrderDividends(orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime))
		dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime) // 修改订单状态 - 异步任务
	}
	dingo.Task(logic.UpdateDeviceInfo, func() {}, orderInfo.DeviceSn) // 修改设备信息 - 异步任务
	dingo.Task(logic.ClearRedisKey, func() {}, orderInfo.TradeNo)     // 清除 redis Key - 异步任务
	return settResult
}

func (logic *OrderLogic) GetPlaceIdsByUserId(loginUserId int) []int {
	placesBranchIds := dao.NewUserDao().GetPlacesId(loginUserId).Unwrap().([]int) // 查询用户ID下的所有关联门店
	userIdArr := dao.NewUserDao().QueryChildUserIds(loginUserId).Unwrap().([]int) // 查询用户ID下所有下级用户ID
	placeIdArr := dao.NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)     // 下级用户ID 下的门店
	placesBranchIds = append(placesBranchIds, placeIdArr...)                      // 合并门店
	placesIds := utils.RemoveRepByMap(placesBranchIds)                            // 去重门店

	var ids []int
	db := global.Orm.Debug().Table("places").Select("id")
	db.Where("id in (?)", placesIds)

	db.Find(&ids)
	return ids
}

//支付宝小程序结束订单
func (logic *OrderLogic) HandleZfbEndOrder(param *request.CloseOrderReq) *resphelper.SettlementResp {
	var settResult *resphelper.SettlementResp
	var wc *paysetting.PaySetting
	devInfo := dao.NewDeviceDao().GetDeviceInfoWithType(param.DeviceSn).Unwrap().(*devices.DeviceType)
	ruleInfo := dao.NewPricesDao().GetLimitPriceDetail(param.ProductId).Unwrap().(*prices.PriceModel)
	orderInfo := dao.NewOrderDao().GetLimitOneOrderInfoByTradeNo(param.TradeNo).Unwrap().(*orders.OrderModel)

	if orderInfo.Appid != "" {
		wc = NewSettingLogic().GetAliPaySetting()
	} else {
		wc = logic.WxConfig
	}

	var useTime, settMoney, returnMoney int64

	log.Println("订单信息==>", orderInfo, "支付金额", orderInfo.PayMoney, orderInfo.BeginAt)
	// 计算订单结算金额
	if orderInfo.FeeMode == 1 { // 计时模式
		//startTime := orderInfo.PayAt
		//if orderInfo.PayAt < orderInfo.BeginAt {
		//	startTime = orderInfo.BeginAt
		//}

		settResult = logic.GetOrderSettMoney(
			int64(orderInfo.BeginAt),
			param.EndTime,
			orderInfo.PayMoney,
			ruleInfo,
			orderInfo.PayFrom,
			0,
		)
	} else { // feeMode == 2 套餐模式
		useTime = param.EndTime - int64(orderInfo.PayAt)
		//if useTime > int64(ruleInfo.UseDuration) {
		//	settMoney = ruleInfo.PayMoney
		//} else {
		//	settMoney = ruleInfo.PayMoney
		//}
		settMoney = ruleInfo.PayMoney
		returnMoney = 0
		if orderInfo.PayMoney > ruleInfo.PayMoney { // 支付的金额大于套餐用时最大金额
			returnMoney = orderInfo.PayMoney - ruleInfo.PayMoney
		}
		settResult = &resphelper.SettlementResp{
			UseTime:     useTime,
			SettMoney:   settMoney,
			ReturnMoney: returnMoney,
		}
	}

	log.Println("打印结算结果 使用时长、结算金额、应退还金额===>", settResult) //

	//使用优惠券
	isCouponInfo, rowsAffected := dao.NewCouponDao().GetByOpenIdCouponInfo(orderInfo.Openid)
	if rowsAffected > 0 {
		//修改金额
		couponInfoModel := isCouponInfo.Unwrap().(*couponinfo.CouponInfo)
		couponData := dao.NewCouponDao().GetCoupon(couponInfoModel.CId).Unwrap().(*coupon.Coupon)
		settResult.SettMoney = settResult.SettMoney - int64(couponData.Discounts)
		if settResult.SettMoney < 0 {
			settResult.SettMoney = 0
		}
		log.Println("打印结算结果 使用时长、结算金额、应退还金额", settResult)
	}
	//如果结算金额为0且押金支付时，全额退款。结算免费时长超过使用时间，返回过来的结算金额等于0
	if settResult.SettMoney == 0 && orderInfo.PayFrom == 2 {
		c := NewAliPayOrderLogic()
		c.TradeNo = orderInfo.TradeNo
		if _, err := c.AliPayTradeRefund(orderInfo.PayMoney, orderInfo.TradeNo, "结束订单"); err != nil {
			logs.Error("AliPayTradeRefund", err)
			return settResult
		}

		// 验证退款成功后再执行
		dingo.Task(logic.CalOrderDividends, func() {}, orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime)) // 计算分红 - 异步任务
		dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime)

		return settResult
	}

	log.Println("打印结算结果，", settResult)

	if settResult.ReturnMoney > 0 { // 退款 - 异步退款
		logs.Info("退款金额===========>", settResult.ReturnMoney)
		c := NewAliPayOrderLogic()
		c.TradeNo = orderInfo.TradeNo
		if _, err := c.AliPayTradeRefund(settResult.ReturnMoney, orderInfo.TradeNo, "结束订单"); err != nil {
			logs.Error("AliPayTradeRefund", err)
			return settResult
		}

		// 验证退款成功后再执行
		dingo.Task(logic.CalOrderDividends, func() {}, orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime)) // 计算分红 - 异步任务
		dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime)                          // 修改订单状态 - 异步任务
	} else { // 完结订单
		if orderInfo.PayFrom == 1 { // 免押支付
			// 先查询订单

			//支付宝
			//queryData,err := NewAliPayOrderLogic().AliPayTradeOrdersQuery(orderInfo.OutTradeNo)
			//if queryData != nil && queryData.Response.TradeStatus == "TRADE_SUCCESS" {}
			queryData, err := wechatpay.ApiQueryPayScoreOrder(param.TradeNo, wc) // 查询微信订单
			if err != nil {
				log.Println("微信订单查询失败")
			}
			if queryData != nil && queryData.Get("state") == "DOING" && queryData.Get("state_description") == "USER_CONFIRM" {
				apiData := NewWxOrderLogic().OrderCompleteApiData(settResult.SettMoney, ruleInfo, orderInfo.PlaceName, devInfo.FeeMode, queryData.Get("location"), wc)
				//respData,err := wechatpay.ApiCompletePayScoreOrder(apiData, param.TradeNo)
				respData, err := wechatpay.ApiCompletePayScoreOrder(apiData, param.TradeNo, wc)
				if err != nil {
					log.Println("完结订单失败")
				}
				//if settResult.SettMoney == 0 {
				//	logic.CouponPayScoreNotify(orderInfo, ruleInfo)
				//}
				log.Println("打印测试完结订单返回值", respData)
			}

			//优惠券异步修改状态
			//logic.CouponPayScoreNotify(orderInfo, ruleInfo)
		} else { // 套餐支付
			//优惠券异步修改状态
			//logic.CouponPayScoreDepositNotify(orderInfo, ruleInfo)
			logic.CalOrderDividends(orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime))
			//dingo.Task(logic.CalOrderDividends, func() {}, orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime)) // 押金支付的分红
			dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime) // 修改订单状态 - 异步任务
		}
	}
	dingo.Task(logic.UpdateDeviceInfo, func() {}, devInfo.DeviceSn) // 修改设备信息 - 异步任务
	dingo.Task(logic.ClearRedisKey, func() {}, orderInfo.TradeNo)   // 清除 redis Key - 异步任务
	return settResult
}

func (logic *OrderLogic) HandleZfbEndOrderV3(param *request.CloseOrderReq, userId int) *resphelper.SettlementResp {
	var settResult *resphelper.SettlementResp
	var wc *paysetting.PaySetting
	devInfo := dao.NewDeviceDao().GetDeviceInfoWithType(param.DeviceSn).Unwrap().(*devices.DeviceType)
	ruleInfo := dao.NewPricesDao().GetLimitPriceDetail(param.ProductId).Unwrap().(*prices.PriceModel)
	orderInfo := dao.NewOrderDao().GetLimitOneOrderInfoByTradeNo(param.TradeNo).Unwrap().(*orders.OrderModel)

	if orderInfo.Appid != "" {
		wc = NewSettingLogic().GetAliPaySetting()
	} else {
		wc = logic.WxConfig
	}

	var useTime, settMoney, returnMoney int64

	log.Println("订单信息", orderInfo, "支付金额", orderInfo.PayMoney, orderInfo.BeginAt)
	// 计算订单结算金额
	if orderInfo.FeeMode == 1 { // 计时模式
		//startTime := orderInfo.PayAt
		//if orderInfo.PayAt < orderInfo.BeginAt {
		//	startTime = orderInfo.BeginAt
		//}

		settResult = logic.GetOrderSettMoney(
			int64(orderInfo.BeginAt),
			param.EndTime,
			orderInfo.PayMoney,
			ruleInfo,
			orderInfo.PayFrom,
			0,
		)
	} else { // feeMode == 2 套餐模式
		useTime = param.EndTime - int64(orderInfo.PayAt)
		//if useTime > int64(ruleInfo.UseDuration) {
		//	settMoney = ruleInfo.PayMoney
		//} else {
		//	settMoney = ruleInfo.PayMoney
		//}
		settMoney = ruleInfo.PayMoney
		returnMoney = 0
		if orderInfo.PayMoney > ruleInfo.PayMoney { // 支付的金额大于套餐用时最大金额
			returnMoney = orderInfo.PayMoney - ruleInfo.PayMoney
		}
		settResult = &resphelper.SettlementResp{
			UseTime:     useTime,
			SettMoney:   settMoney,
			ReturnMoney: returnMoney,
		}
	}

	log.Println("打印结算结果 使用时长、结算金额、应退还金额", settResult) //

	//使用优惠券
	isCouponInfo, rowsAffected := dao.NewCouponDao().GetByOpenIdCouponInfo(orderInfo.Openid)
	if rowsAffected > 0 {
		//修改金额
		couponInfoModel := isCouponInfo.Unwrap().(*couponinfo.CouponInfo)
		couponData := dao.NewCouponDao().GetCoupon(couponInfoModel.CId).Unwrap().(*coupon.Coupon)
		settResult.SettMoney = settResult.SettMoney - int64(couponData.Discounts)
		if settResult.SettMoney < 0 {
			settResult.SettMoney = 0
		}
		log.Println("打印结算结果 使用时长、结算金额、应退还金额", settResult)
	}
	//如果结算金额为0且押金支付时，全额退款。结算免费时长超过使用时间，返回过来的结算金额等于0
	if settResult.SettMoney == 0 && orderInfo.PayFrom == 2 {
		c := NewAliPayOrderLogic()
		c.TradeNo = orderInfo.TradeNo
		if _, err := c.AliPayTradeRefund(orderInfo.PayMoney, orderInfo.TradeNo, "结束订单"); err != nil {
			logs.Error("AliPayTradeRefund", err)
			return settResult
		}

		// 验证退款成功后再执行
		dingo.Task(logic.CalOrderDividends, func() {}, orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime)) // 计算分红 - 异步任务
		dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime)

		return settResult
	}

	log.Println("打印结算结果，", settResult)

	if settResult.ReturnMoney > 0 { // 退款 - 异步退款
		c := NewAliPayOrderLogic()
		c.TradeNo = orderInfo.TradeNo
		if _, err := c.AliPayTradeRefund(settResult.ReturnMoney, orderInfo.TradeNo, "结束订单"); err != nil {
			logs.Error("AliPayTradeRefund", err)
			return settResult
		}

		//// 退款至余额
		//tx, key := dbs.GormBegin("update member balance ==> refund fee")
		//// 订单退款，退款至余额
		//rechargeMoneyUpdateData := memberdao.NewMemberDao().UpdateBalanceAmount(tx, &membermodel.MemberPclBalance{
		//	MemberId:    userId,
		//	Amount:      int(settResult.ReturnMoney),
		//	Type:        4,
		//	TradeNo:     param.TradeNo,
		//	Description: fmt.Sprintf(`订单退款`),
		//	CreateTime:  time.Now().Format("2006-01-02 15:04:05"),
		//	UpdateTime:  time.Now().Format("2006-01-02 15:04:05"),
		//})
		//if rechargeMoneyUpdateData.Err != nil {
		//	dbs.GormRollback(tx, key, rechargeMoneyUpdateData.Err)
		//	return settResult
		//}
		//dbs.GormCommit(tx, key)

		// 验证退款成功后再执行
		dingo.Task(logic.CalOrderDividends, func() {}, orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime)) // 计算分红 - 异步任务
		dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime)                          // 修改订单状态 - 异步任务
	} else { // 完结订单
		if orderInfo.PayFrom == 1 { // 免押支付
			// 先查询订单

			//支付宝
			//queryData,err := NewAliPayOrderLogic().AliPayTradeOrdersQuery(orderInfo.OutTradeNo)
			//if queryData != nil && queryData.Response.TradeStatus == "TRADE_SUCCESS" {}
			queryData, err := wechatpay.ApiQueryPayScoreOrder(param.TradeNo, wc) // 查询微信订单
			if err != nil {
				log.Println("微信订单查询失败")
			}
			if queryData != nil && queryData.Get("state") == "DOING" && queryData.Get("state_description") == "USER_CONFIRM" {
				apiData := NewWxOrderLogic().OrderCompleteApiData(settResult.SettMoney, ruleInfo, orderInfo.PlaceName, devInfo.FeeMode, queryData.Get("location"), wc)
				//respData,err := wechatpay.ApiCompletePayScoreOrder(apiData, param.TradeNo)
				respData, err := wechatpay.ApiCompletePayScoreOrder(apiData, param.TradeNo, wc)
				if err != nil {
					log.Println("完结订单失败")
				}
				//if settResult.SettMoney == 0 {
				//	logic.CouponPayScoreNotify(orderInfo, ruleInfo)
				//}
				log.Println("打印测试完结订单返回值", respData)
			}

			//优惠券异步修改状态
			//logic.CouponPayScoreNotify(orderInfo, ruleInfo)
		} else { // 套餐支付
			//优惠券异步修改状态
			//logic.CouponPayScoreDepositNotify(orderInfo, ruleInfo)
			logic.CalOrderDividends(orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime))
			//dingo.Task(logic.CalOrderDividends, func() {}, orderInfo, devInfo, settResult.SettMoney, int64(param.EndTime)) // 押金支付的分红
			dingo.Task(logic.UpdateOrderInfo, func() {}, orderInfo.Id, settResult, param.EndTime) // 修改订单状态 - 异步任务
		}
	}
	dingo.Task(logic.UpdateDeviceInfo, func() {}, devInfo.DeviceSn) // 修改设备信息 - 异步任务
	dingo.Task(logic.ClearRedisKey, func() {}, orderInfo.TradeNo)   // 清除 redis Key - 异步任务
	return settResult
}

//HandleCancelEndOrder 不完结取消订单
func (logic *OrderLogic) HandleCancelEndOrder(param *request.CloseOrderReq) (*wechatpay.PayData, error) {
	var wc *paysetting.PaySetting
	devInfo := dao.NewDeviceDao().FetchDeviceInfoWithType(param.DeviceSn).Unwrap().(*devices.DeviceType)
	//ruleInfo := dao.NewPricesDao().GetPriceDetail(param.ProductId).Unwrap().(*prices.PriceModel)
	orderInfo := dao.NewOrderDao().GetOrderInfoByTradeNo(param.TradeNo).Unwrap().(*orders.OrderModel)

	if orderInfo.Appid != "" {
		wc = NewSettingLogic().GetPaySettingByAppid(orderInfo.Appid)
	} else {
		wc = logic.WxConfig
	}
	queryData, err := wechatpay.ApiQueryPayScoreOrder(param.TradeNo, wc) // 查询微信订单
	if err != nil {                                                      // 查询订单失败
		return nil, err
	}
	param.EndTime = time.Now().Unix()
	//var useTime, settMoney, returnMoney int64
	//// 计算订单结算金额
	//if devInfo.FeeMode == 2 { // feeMode == 2 套餐模式
	//	useTime = param.EndTime - int64(orderInfo.PayAt)
	//	settMoney = ruleInfo.PayMoney
	//	returnMoney = 0
	//	if orderInfo.PayMoney > ruleInfo.PayMoney { // 支付的金额大于套餐用时最大金额
	//		returnMoney = orderInfo.PayMoney - ruleInfo.PayMoney
	//	}
	//	settResult = &resphelper.SettlementResp{
	//		UseTime:     useTime,
	//		SettMoney:   settMoney,
	//		ReturnMoney: returnMoney,
	//	}
	//}
	if orderInfo.PayFrom == 1 { // 免押支付
		log.Println("打印测试数据，查询微信订单结果", queryData)
		apiParam := wechatpay.NewPayData()
		//apiParam.Set("out_order_no", orderInfo.TradeNo)
		apiParam.Set("appid", wc.AppId)
		apiParam.Set("service_id", wc.ServerId)
		apiParam.Set("reason", "撤销订单")
		respData, err := wechatpay.ApiCancelPayScoreOrder(apiParam, param.TradeNo, wc)
		if err != nil {
			return nil, err
		}

		//dingo.Task(logic.UpdateCancelEndInfo, func() {}, orderInfo.Id, settResult, param.EndTime) // 修改订单状态 - 异步任务
		logic.UpdateCancelEndInfo(orderInfo.Id, param.EndTime)

		dingo.Task(logic.UpdateDeviceInfo, func() {}, devInfo.DeviceSn) // 修改设备信息 - 异步任务
		dingo.Task(logic.ClearRedisKey, func() {}, orderInfo.TradeNo)   // 清除 redis Key - 异步任务
		log.Println("取消支付分订单:", respData)
		if respData.Get("order_id") != "" {
			return respData, err
		}

	} else {
		return nil, errors.New("押金支付请选择退款")
	}
	return nil, err
}

// HandleRefundApiParamV2 退款参数处理
func (logic *OrderLogic) HandleRefundApiParamV2(money, returnMoney int64, outTradeNo, refundDesc, refundNotifyUrl string) *wxpay.PayData {
	var pd = wxpay.NewPayData()
	refundNo := utils.Join(global.Const.Pre.RefundPre, time.Now().Format("20060102150405"), utils.GetRandomInt(6)) // 退款订单号
	pd.Set("transaction_id", outTradeNo)                                                                           // 微信生成的订单号
	pd.Set("out_refund_no", refundNo)                                                                              // 退款订单号
	pd.Set("total_fee", money)                                                                                     // 订单总金额
	pd.Set("refund_fee", returnMoney)                                                                              // 退款金额
	pd.Set("refund_fee_type", "CNY")                                                                               // 货币种类
	pd.Set("refund_desc", refundDesc)                                                                              // 退款原因
	pd.Set("notify_url", refundNotifyUrl)                                                                          // 退款成功通知url
	return pd
}

/**
  GetOrderSettMoney 计时结算逻辑算法
  @satrtTime 开始时间
  @endTime  结束时间
  @payMoney 支付金额
  @ruleInfo 计费规则
  @payFrom 支付来源
  @reduceTime 时长减免
*/
func (logic *OrderLogic) GetOrderSettMoney(startTime, endTime, payMoney int64, ruleInfo *prices.PriceModel, payFrom int8, reduceTime int64) (settResult *resphelper.SettlementResp) {
	var useTime, settMoney, returnMoney, useTimeHour int64
	useTime = endTime - (startTime + reduceTime*60)              // 使用时长
	if useTime <= 0 || useTime <= int64(ruleInfo.FreeTimes)*60 { // 还在免费使用时长范围内，结算金额为 0
		settMoney = 0
		returnMoney = payMoney
	} else {
		useTime = useTime - int64(ruleInfo.FreeTimes)*60 // 使用时长 - 免费时长
		if useTime <= int64(ruleInfo.BaseTimes*60) {     // 使用时长 < 最低使用时长
			settMoney = ruleInfo.BasePrice // 最低使用价格
		} else {
			useTime = useTime - int64(ruleInfo.BaseTimes*60) // 使用时长 - 最低使用时长
			t := useTime / int64(ruleInfo.PayInterval*60)    // 求商
			if useTime%int64(ruleInfo.PayInterval*60) > 0 {
				t = t + 1
			} // 求余
			settMoney = ruleInfo.BasePrice + t*ruleInfo.PayIntervalPrice
		}
		returnMoney = payMoney - settMoney // 退还金额 (订单支付金额 - 结算金额)
	}
	//if useTime <= 0 { // 还在免费使用时长范围内，结算金额为 0
	//	settMoney = 0
	//	returnMoney = 0
	//} else {
	//	if ruleInfo.FreeTimes > 0 && ruleInfo.FreeTimes < 15 { // 有设置免费时长的 15分钟以内的算法
	//		if useTime <= int64(ruleInfo.FreeTimes)*60 { // 免费时长内,免费使用
	//			settMoney = 0
	//			returnMoney = 0
	//		} else { // 超出免费时长,计算价格
	//			h := int64(ruleInfo.BaseTimes / ruleInfo.PayInterval)
	//			useTimeHour = helper.UseTimeToHour(useTime, int64(ruleInfo.PayInterval))
	//			if useTimeHour <= h {
	//				settMoney = ruleInfo.BasePrice // 最低使用价格
	//			} else {
	//				// 最低使用价格 + 每小时价格
	//				settMoney = ruleInfo.BasePrice + (useTimeHour-h)*ruleInfo.PayIntervalPrice
	//			}
	//			returnMoney = payMoney - settMoney // 退还金额 (订单支付金额 - 结算金额)
	//		}
	//	} else if ruleInfo.FreeTimes >= 15 { // 有设置免费时长的 大于15分钟的算法
	//		if useTime <= int64(ruleInfo.FreeTimes)*60 { // 免费时长内,免费使用
	//			settMoney = 0
	//			returnMoney = 0
	//		} else {
	//			useTime = useTime - int64(ruleInfo.FreeTimes)*60
	//			useTimeHour = helper.UseTimeToHour(useTime, int64(ruleInfo.PayInterval))
	//			settMoney = useTimeHour * ruleInfo.PayIntervalPrice // 结算金额
	//			returnMoney = payMoney - settMoney
	//		}
	//	} else {
	//		h := int64(ruleInfo.BaseTimes / ruleInfo.PayInterval)
	//		useTimeHour = helper.UseTimeToHour(useTime, int64(ruleInfo.PayInterval))
	//		if useTimeHour <= h {
	//			settMoney = ruleInfo.BasePrice // 最低使用价格
	//		} else {
	//			// 最低使用价格 + 每小时价格
	//			settMoney = ruleInfo.BasePrice + (useTimeHour-h)*ruleInfo.PayIntervalPrice
	//		}
	//		returnMoney = payMoney - settMoney // 退还金额 (订单支付金额 - 结算金额)
	//	}
	//}

	log.Println("使用时长", useTime, useTimeHour, "结算金额", settMoney, "支付金额", payMoney)

	if payFrom == 1 {
		returnMoney = 0
	} // 免押使用，退款金额为 0

	if useTime > int64(ruleInfo.MaxTime*60) { // 使用时长大于最大使用时长
		settMoney = ruleInfo.MaxPayPrice
		returnMoney = 0
	}

	if settMoney > ruleInfo.MaxPayPrice { // 结算金额大于封顶金额（最大金额）
		settMoney = ruleInfo.MaxPayPrice
		returnMoney = 0
	}

	// 结算信息
	settResult = &resphelper.SettlementResp{
		UseTime:     endTime - startTime, // 用户真实使用时长
		SettMoney:   settMoney,           // 产生费用
		ReturnMoney: returnMoney,         // 退款金额
	}

	return settResult
}

// HandleRefund 退款
func (logic *OrderLogic) HandleRefund(param ...interface{}) {
	apiData := param[0].(*wxpay.PayData)
	wc := param[1].(*paysetting.PaySetting)
	log.Println("退款参数", apiData)
	logic.PayClient = wxpay.NewCertPayClient(wc)
	respData, err := wxpay.ApiRefund(logic.PayClient, apiData, wc)
	if err != nil {
		log.Println(err)
	}
	//&{map[appid:wx9ab574042f46a487
	//err_code:PARAM_ERROR
	//err_code_des:微信订单号非法
	//mch_id:1600369044
	//nonce_str:RNOmDhqkrqSsQiQM
	//result_code:FAIL
	//return_code:SUCCESS
	//return_msg:OK
	//sign:7D7E00103CCA3C7A812AB19DFCEC4119FF153952260A4A1C6C58B6D09A5E466A]}
	log.Println(respData)
	// 记录退款日志 - 待开发
}

// UpdateOrderInfo 更新订单信息 - 异步处理
func (logic *OrderLogic) UpdateOrderInfo(param ...interface{}) {
	orderId := param[0].(int)
	settResult := param[1].(*resphelper.SettlementResp)
	endTime := param[2].(int64)

	m := orders.New().Mutate(
		orders.WithId(orderId),
		orders.WithEndAt(dingo.Time(endTime)),            // 订单结束日期
		orders.WithState(5),                              // 订单状态status 5:已完成
		orders.WithRefundMoney(settResult.ReturnMoney),   // 退款金额
		orders.WithRefundAt(dingo.Time(endTime)),         // 退款时间
		orders.WithSettlementMoney(settResult.SettMoney), // 结算金额
		orders.WithSettlementMoneyStr(decimal.NewFromInt(settResult.SettMoney).Div(decimal.NewFromInt(100)).StringFixed(2)),
		orders.WithSettlementState(3), // 3已结算
		orders.WithSettlementWay(1),   // 1微信支付
		orders.WithCouponType(settResult.CouponType),
		orders.WithCouponMoney(settResult.ReduceMoney),
	)
	dao.NewOrderDao().UpdateOrder(m).Unwrap()
}

func (logic *OrderLogic) UpdateCancelEndInfo(param ...interface{}) {
	orderId := param[0].(int)
	endTime := param[1].(int64)

	m := orders.New().Mutate(
		orders.WithId(orderId),
		orders.WithEndAt(dingo.Time(endTime)),    // 订单结束日期
		orders.WithState(3),                      // 订单状态status 3:已撤销
		orders.WithRefundMoney(0),                // 退款金额
		orders.WithRefundAt(dingo.Time(endTime)), // 退款时间
		orders.WithSettlementMoney(0),            // 结算金额
		orders.WithSettlementMoneyStr("0"),
		orders.WithSettlementState(3), // 3已撤销
		orders.WithSettlementWay(1),   // 1微信支付

	)
	dao.NewOrderDao().UpdateOrder(m).Unwrap()
}

// UpdateDeviceInfo 更新设备信息 - 异步处理
func (logic *OrderLogic) UpdateDeviceInfo(param ...interface{}) {
	deviceSn := param[0].(string)
	m := devices.New().Mutate(
		devices.WithDeviceSn(deviceSn),
		devices.WithUpdateAt(dingo.Time(time.Now().Unix())),
		devices.WithStatus(2), // 状态改为已部署
	)
	dao.NewDeviceDao().UpdateDeviceBySn(m).Unwrap()
}

// ClearRedisKey 清除缓存Key - 异步处理
func (logic *OrderLogic) ClearRedisKey(param ...interface{}) {
	tradeNo := param[0].(string)
	keyOrderPassword := utils.Join(tradeNo, "-password") // 密码
	keyOrderStatus := utils.Join(tradeNo, "-status")     // 状态
	keyOrderUseTime := utils.Join(tradeNo, "-usetime")   // 使用时长
	keyOrderPwdCount := utils.Join(tradeNo, "-pwdcount") // 密码重置次数
	global.Rdb.Del(context.Background(), keyOrderPassword, keyOrderUseTime, keyOrderPwdCount, keyOrderStatus)
}

// CalAutomateOrderDividends 售货机订单分红
func (logic *OrderLogic) CalAutomateOrderDividends(tradeNo string) error {
	var list []*request.GetAdminAutomateOrderWaitDividendsRes
	// 查询订单获取 place_id,device_sn
	orderInfo := dao.NewAutomateDaoDao().GetAdminAutomateOrderInfoByTradeNo(tradeNo).Unwrap().(*automate.OrderModel)
	// 判断门店是否开启 首单
	firstOrder := dao.NewAutomateDaoDao().GetOrderFirstByPlaceIdAndDeviceSn(orderInfo.PlaceId, orderInfo.DeviceSn)
	if firstOrder.IsOpenFirst == 1 && firstOrder.Id == orderInfo.Id { // 首单
		list = dao.NewAutomateDaoDao().GetAutomateOrderWaitDividends(tradeNo, 1)
		if len(list) == 0 {
			fmt.Sprintf(tradeNo, "查询失败，未分红")
			return nil
		}
	} else {
		list = dao.NewAutomateDaoDao().GetAutomateOrderWaitDividends(tradeNo, 0)
		if len(list) == 0 {
			fmt.Sprintf(tradeNo, "查询失败，未分红")
			return nil
		}
	}

	sort.Slice(list, func(i, j int) bool {
		if list[i].ProfitProportion != list[j].ProfitProportion {
			return list[i].ProfitProportion < list[j].ProfitProportion
		}

		IsAdmins := fmt.Sprintf("[%d][%d][%d][%d][%d][%d][%d][%d][%d][%d]",
			helper.TypeNumIsAdminMerchant, helper.TypeNumIsAdminBd, helper.TypeNumIsAdminKaProject, helper.TypeNumIsAdminRegion, helper.TypeNumIsAdminResource,
			helper.TypeNumIsAdminStaff, helper.TypeNumIsAdminPartner, helper.TypeNumIsAdminBranch, helper.TypeNumIsAdminOperator, helper.TypeNumIsAdminAdministrator)
		iIndex := strings.Index(IsAdmins, fmt.Sprintf("[%d]", list[i].IsAdmin))
		jIndex := strings.Index(IsAdmins, fmt.Sprintf("[%d]", list[j].IsAdmin))
		return iIndex < jIndex
	})

	profit := 0
	var dbList []*automate.DividendsLogDb
	for _, item := range list {
		if item.IsAdmin == 0 {
			return errors.New("用户关联错误")
		}

		money := 0
		if item.ProfitProportion-profit > 0 {
			money = int(float64(item.ProfitProportion-profit) / 100 * float64(item.Amount))
		}
		profit = item.ProfitProportion
		dbList = append(dbList, &automate.DividendsLogDb{
			UserId:           item.UserId,
			PlaceId:          item.PlaceId,
			Amount:           money,
			ProfitProportion: item.ProfitProportion,
			TradeNo:          item.TradeNo,
			DeviceSn:         item.DeviceSn,
			PlaceName:        item.PlaceName,
			UserName:         item.UserName,
			EndDate:          item.EndDate,
			EndMonth:         item.EndMonth,
		})
	}
	return dao.NewAutomateDaoDao().InsertAutomateOrderDividends(dbList)
}

// 层级用户去重复
func repetitionUserList(userList []*users.UserModel) (list []*users.UserModel) {
	m := map[int]bool{}
	for _, item := range userList {
		if m[item.ID] || item.IsDivinds == helper.TypeNumDividendsStatusNo {
			continue
		}
		list = append(list, item)
		m[item.ID] = true
	}

	return list
}

// 递归查询所有代理商/KA
func QueryParentListAll(userInfo *users.UserModel, userList []*users.UserModel, num int) ([]*users.UserModel, error) {
	num++
	if userInfo.ParentID <= 0 || num > 100 {
		return userList, nil
	}

	resultUserInfo := dao.NewUserDao().GetUserInfoById(userInfo.ParentID)
	if resultUserInfo.Err != nil {
		return userList, resultUserInfo.Err
	}

	targetUserInfo := resultUserInfo.Unwrap().(*users.UserModel)
	userList = append(userList, targetUserInfo)

	return QueryParentListAll(targetUserInfo, userList, num)
}

// InsertRewardLog 新增分红日志
func (logic *OrderLogic) InsertRewardLog(tx *gorm.DB, curruserInfo *users.UserModel, orderInfo *orders.OrderModel, devInfo *devices.DeviceType, settMoney int64, money decimal.Decimal, endTime int64) error {
	dividends := &dividendslog.DividendsLog{}
	dividends.SharedMode = devInfo.SharedMode
	dividends.UserId = curruserInfo.ID
	dividends.UserName = curruserInfo.Name
	dividends.ProfitProportion = int8(curruserInfo.ProfitProportion)
	dividends.UpdateAt = dingo.Time(endTime)
	dividends.CreateAt = dingo.Time(endTime)
	dividends.EndMonth = time.Unix(endTime, 0).Format("2006-01")
	dividends.EndDate = time.Unix(endTime, 0).Format("2006-01-02")
	dividends.ProfitType = int8(curruserInfo.ProfitType)
	dividends.PlaceId = orderInfo.PlaceId
	dividends.PlaceName = orderInfo.PlaceName
	dividends.TradeNo = orderInfo.TradeNo
	dividends.FeeMode = orderInfo.FeeMode

	dividends.State = 5 // 已完成
	fm, _ := money.Float64()
	dividends.Money = int64(fm)
	dividends.MoneyStr = money.Div(decimal.NewFromInt(100)).String() // 代理商获得的金额
	//dividends.MoneyStr = money.String() // 代理商获得的金额
	dividends.MemberName = orderInfo.MemberName
	dividends.MemberId = orderInfo.MemberId
	dividends.PayMoney = orderInfo.PayMoney
	dividends.PayMoneyStr = utils.Fen2Yuan(orderInfo.PayMoney)
	dividends.PayAt = orderInfo.PayAt
	dividends.SettlementAt = dingo.Time(endTime)

	dividends.DeviceTypeName = devInfo.DeviceTypeName
	dividends.DeviceTypeID = devInfo.DeviceTypeId
	dividends.FeeMode = orderInfo.FeeMode
	dividends.DeviceSn = orderInfo.DeviceSn
	dividends.SettlementMoneyStr = utils.Fen2Yuan(settMoney)
	dividends.SettlementMoney = settMoney

	if result := dao.NewOrderDao().InsertDividends(tx, dividends); result.Err != nil {
		return result.Err
	}
	return nil
	//.Unwrap()
}

func (logic *OrderLogic) CouponPayScoreNotify(orderInfo *orders.OrderModel, ruleInfo *prices.PriceModel) {

	//orderInfo := param[0].(*orders.OrderModel)
	//ruleInfo := param[1].(*prices.PriceModel)
	//修改状态
	couponInfo := dao.NewCouponDao().GetCouponInfoOpenId(orderInfo.Openid).Unwrap().(*couponinfo.CouponInfo)
	log.Println("我进来改优惠券状态了")
	//有使用过的
	if couponInfo.Id == 0 {
		return
	}
	//log.Println("支付分订单确认结果参数：", orderInfo)
	log.Println("订单编号", orderInfo.TradeNo, "openId", orderInfo.Openid, "订单金额：", ruleInfo.PayMoney)
	//collection := wechatpay.NewPayData()
	//_ = collection.FromJsonStr(resultData.Get("collection"))
	// 状态 USER_PAYING：待支付 USER_PAID：已支付
	totalAmount := ruleInfo.PayMoney        // 总金额
	paidAmount := orderInfo.SettlementMoney // 已支付金额

	//paid_amount
	couponInfoModel := &couponinfo.CouponInfo{}
	couponInfoModel.Status = 2
	couponInfoModel.OrderId = orderInfo.TradeNo
	dao.NewCouponDao().CouponInfoByOpenIdEditDao(orderInfo.Openid, couponInfoModel).Unwrap()

	couponData := dao.NewCouponDao().GetCoupon(couponInfo.CId).Unwrap().(*coupon.Coupon)
	//新增日志
	couponLogModel := couponlog.CouponLog{}
	couponLogModel.CId = couponInfo.CId
	couponLogModel.UserId = orderInfo.UserId
	couponLogModel.OrderId = orderInfo.TradeNo // 对应订单标识
	couponLogModel.IsUse = 1                   //是否使用
	//wxMoney, _ := strconv.Atoi(resultData.Get("paid_amount"))
	couponLogModel.ActualMoney = int(totalAmount) - couponData.Discounts
	if couponLogModel.ActualMoney < 0 {
		couponLogModel.ActualMoney = 0
	}
	couponLogModel.OrderMoney = int(paidAmount)
	couponLogModel.FaceValue = couponData.Discounts

	if paidAmount > 0 || orderInfo.TradeNo != "" || orderInfo.Openid != "" || couponInfo.CId > 0 || couponInfo.UserId > 0 {
		dao.NewCouponLogDao().CouponLogSaveDao(&couponLogModel).Unwrap()
	}

}

//押金修改优惠券状态
func (logic *OrderLogic) CouponPayScoreDepositNotify(orderInfo *orders.OrderModel, ruleInfo *prices.PriceModel) {
	//devInfo := param[0].(*devices.DeviceType)
	//ruleInfo := param[1].(*prices.PriceModel)
	//orderInfo := param[0].(*orders.OrderModel)
	//ruleInfo := param[1].(*prices.PriceModel)
	//log.Println("押金修改优惠券状态：", resultData)
	//修改状态
	couponInfo := dao.NewCouponDao().GetCouponInfoOpenId(orderInfo.Openid).Unwrap().(*couponinfo.CouponInfo)

	//有使用过的
	if couponInfo.Id == 0 {
		return
	}

	log.Println("订单编号", orderInfo.TradeNo, "openId", orderInfo.Openid, "订单金额：", ruleInfo.PayMoney)
	//collection := wechatpay.NewPayData()
	//_ = collection.FromJsonStr(resultData.Get("collection"))
	// 状态 USER_PAYING：待支付 USER_PAID：已支付
	totalAmount := ruleInfo.PayMoney        // 总金额
	paidAmount := orderInfo.SettlementMoney // 已支付金额

	//paid_amount
	couponInfoModel := &couponinfo.CouponInfo{}
	couponInfoModel.Status = 2
	couponInfoModel.OrderId = orderInfo.TradeNo
	dao.NewCouponDao().CouponInfoByOpenIdEditDao(orderInfo.Openid, couponInfoModel).Unwrap()

	couponData := dao.NewCouponDao().GetCoupon(couponInfo.CId).Unwrap().(*coupon.Coupon)
	//新增日志
	couponLogModel := couponlog.CouponLog{}
	couponLogModel.CId = couponInfo.CId
	couponLogModel.UserId = orderInfo.UserId
	couponLogModel.OrderId = orderInfo.TradeNo // 对应订单标识
	couponLogModel.IsUse = 1                   //是否使用
	//wxMoney, _ := strconv.Atoi(resultData.Get("paid_amount"))
	couponLogModel.ActualMoney = int(totalAmount) - couponData.Discounts
	if couponLogModel.ActualMoney < 0 {
		couponLogModel.ActualMoney = 0
	}
	couponLogModel.OrderMoney = int(paidAmount)
	couponLogModel.FaceValue = couponData.Discounts

	if paidAmount > 0 || orderInfo.TradeNo != "" || orderInfo.Openid != "" || couponInfo.CId > 0 || couponInfo.UserId > 0 {
		dao.NewCouponLogDao().CouponLogSaveDao(&couponLogModel).Unwrap()
	}

}

// -------------------------------- 撤销订单 --------------------------------- //

//全额退款
func (logic *OrderLogic) HandleWxCancelOrder(tradeNo, createTime string) error {
	orderInfo := dao.NewOrderDao().GetOrderInfoByTradeNoAndCreateTime(tradeNo, createTime).Unwrap().(*orders.OrderModel)
	//log.Println("打印测试撤销订单-订单信息", orderInfo)
	var wc *paysetting.PaySetting

	if orderInfo.Appid != "" {
		wc = NewSettingLogic().GetPaySettingByAppid(orderInfo.Appid)
	} else {
		wc = logic.WxConfig
	}
	if orderInfo.State == 2 { // 服务中的订单
		return errors.New("请先完结订单")
		// 取消商户订单
		//if orderInfo.PayFrom == 1 { // 免押
		//	apiParam := wechatpay.NewPayData()
		//	//apiParam.Set("out_order_no", orderInfo.TradeNo)
		//	apiParam.Set("appid", wechatpay.ConfigV3.AppId())
		//	apiParam.Set("service_id", wechatpay.ConfigV3.ServerId())
		//	apiParam.Set("reason", "撤销订单")
		//	respData, err := wechatpay.ApiCancelPayScoreOrder(apiParam, orderInfo.TradeNo)
		//	if err != nil {
		//		zap.L().Error("微信支付支订单确认，撤销微信订单失败，notifyhandler:HandlePayScoreResult")
		//		return errors.New("微信支付支订单确认，撤销微信订单失败，notifyhandler:HandlePayScoreResult")
		//	}
		//	log.Println("打印测试数据，撤销微信订单结果", respData)
		//} else { // 押金
		//	apiData := wxpay.NewPayData()
		//	apiData.Set("transaction_id", orderInfo.OutTradeNo)
		//	payClient := wxpay.NewPayClient(nil)
		//	respData, err := wxpay.ApiOrderQuery(payClient, apiData)
		//	if err != nil {
		//		zap.L().Error("error order query - 微信订单查询失败")
		//		return errors.New("error order query - 微信订单查询失败")
		//	}
		//	log.Println("打印测试数据，查询微信订单结果(押金支付)", respData)
		//	if respData.Get("return_code") == wxpay.RCSuccess &&
		//		respData.Get("result_code") == wxpay.RCSuccess {
		//		// 退款
		//		apiParam := logic.HandleRefundApiParamV2(
		//			orderInfo.Money, // 订单金额
		//			//settResult.ReturnMoney,
		//			orderInfo.SettlementMoney, // 退款金额为结算金额
		//			orderInfo.OutTradeNo,
		//			"撤销订单")
		//
		//		logic.PayClient = wxpay.NewCertPayClient(wc)
		//		rData, err := wxpay.ApiRefund(logic.PayClient, apiParam)
		//		log.Println("打印测试数据---退款返回后的数据", rData)
		//		if err != nil {
		//			return err
		//		}
		//		return nil
		//	}
		//	//return errors.New("请先完结订单，再撤销")
		//}
	}

	// 订单已完结 才退款
	// 已分红的金额暂时不做回滚
	// 这个钱先帖，到时候订单详情里回滚
	if orderInfo.State == 5 {
		if orderInfo.PayFrom == 1 { // 免押支付
			// 先查询订单
			respData, err := wechatpay.ApiQueryPayScoreOrder(orderInfo.TradeNo, wc) // 查询微信订单
			if err != nil {
				zap.L().Error("微信支付支订单确认，查询微信订单失败，notifyhandler:HandlePayScoreResult")
				return errors.New("微信支付支订单确认，查询微信订单失败，notifyhandler:HandlePayScoreResult")
			}
			log.Println("打印测试数据，查询微信订单结果", respData)
			if respData.Get("state") == "DONE" {
				if respData.Get("collection") != "" {
					apiData := wechatpay.NewPayData()
					_ = apiData.FromJsonStr(respData.Get("collection"))
					var details []map[string]interface{}
					_ = json.Unmarshal([]byte(apiData.Get("details")), &details)
					log.Println("打印测试退款操作的回调地址 RefundNotifyUrl", wc.RefundNotifyUrl)
					apiParam := logic.HandleRefundApiParamV3(
						orderInfo,
						details[0]["transaction_id"].(string),
						"撤销订单",
						orderInfo.SettlementMoney,
						wc.RefundNotifyUrl)
					log.Println("打印测试退款操作的参数 apiParam", apiParam)
					rData, err := wechatpay.ApiRefundsPayScore(apiParam, wc)

					log.Println("打印测试数据---退款返回后的数据", rData)
					if err != nil {
						return err
					}

					//-----------------订单撤销

					//

					////查询退款总额
					//refundsTotal := dao.NewOrderDao().GetRefundsByTransactionIdTotal(details[0]["transaction_id"].(string)).Unwrap().(int64)
					//dividends := orderInfo.SettlementMoney - refundsTotal
					//if dividends <= 0 {
					//	orderInfo.State = 3
					//	dao.NewOrderDao().UpdateOrder(orderInfo).Unwrap()
					//	//存在分红金额，删除之前分红数据
					//	dao.NewOrderDao().DeleteDividendsLog(orderInfo.TradeNo).Unwrap()
					//	return nil
					//} else {
					//	//存在分红金额，删除之前分红数据
					//	dao.NewOrderDao().DeleteDividendsLog(orderInfo.TradeNo).Unwrap()
					//
					//	//查询订单对应的设备信息
					//	deviceInfo := dao.NewOrderDao().GetDeviceInfo(orderInfo.DeviceSn).Unwrap().(*devices.DeviceType)
					//	orderModel := &orders.OrderModel{}
					//	orderModel.Id = orderInfo.Id
					//	orderModel.SettlementMoney = dividends
					//	orderModel.SettlementMoneyStr = decimal.NewFromInt(dividends).Div(decimal.NewFromInt(100)).StringFixed(2)
					//	dao.NewOrderDao().UpdateOrder(orderModel).Unwrap()
					//	//orderInfo.SettlementMoney = dividends
					//	dingo.Task(logic.CalOrderDividends, func() {}, orderInfo, deviceInfo, dividends, int64(orderInfo.EndAt)) // 计算分红 - 异步任务
					//}

					return nil
					//if rData.Get("status") == "SUCCESS" { // 退款成功
					//	log.Println("退款成功")
					//	// 修改订单状态
					//	orderInfo.State = 3
					//	dao.NewOrderDao().UpdateOrder(orderInfo).Unwrap()
					//	return nil
					//} else {
					//	return errors.New(rData.Get("status"))
					//}
				}
			}
		} else { // 押金支付
			apiData := wxpay.NewPayData()
			apiData.Set("transaction_id", orderInfo.OutTradeNo)
			payClient := wxpay.NewPayClient(nil)
			respData, err := wxpay.ApiOrderQuery(payClient, apiData, wc)
			if err != nil {
				zap.L().Error("error order query - 微信订单查询失败")
				return errors.New("error order query - 微信订单查询失败")
			}
			log.Println("打印测试数据，查询微信订单结果(押金支付)", respData)
			if respData.Get("return_code") == wxpay.RCSuccess &&
				respData.Get("result_code") == wxpay.RCSuccess {
				// 退款

				apiParam := logic.HandleRefundApiParamV3(
					orderInfo,
					orderInfo.OutTradeNo,
					"撤销订单",
					orderInfo.SettlementMoney, // 退款金额为结算金额
					wc.RefundNotifyUrl)
				rData, err := wechatpay.ApiRefundsPayScore(apiParam, wc)

				//apiParam := logic.HandleRefundApiParamV2(
				//	orderInfo.Money, // 订单金额
				//	//settResult.ReturnMoney,
				//	orderInfo.SettlementMoney, // 退款金额为结算金额
				//	orderInfo.OutTradeNo,
				//	"撤销订单", wc.RefundNotifyUrl)
				//
				//logic.PayClient = wxpay.NewCertPayClient(wc)
				//rData, err := wxpay.ApiRefund(logic.PayClient, apiParam, wc)
				log.Println("打印测试数据---退款返回后的数据", rData)
				if err != nil {
					return err
				}

				//-----------------订单撤销

				////查询退款总额
				//refundsTotal := dao.NewOrderDao().GetRefundsByTransactionIdTotal(orderInfo.OutTradeNo).Unwrap().(int64)
				//dividends := orderInfo.SettlementMoney - refundsTotal
				//if dividends <= 0 {
				//orderInfo.State = 3
				//dao.NewOrderDao().UpdateOrder(orderInfo).Unwrap()
				////存在分红金额，删除之前分红数据
				//dao.NewOrderDao().DeleteDividendsLog(orderInfo.TradeNo).Unwrap()
				//return nil
				//} else {
				//	//存在分红金额，删除之前分红数据
				//	dao.NewOrderDao().DeleteDividendsLog(orderInfo.TradeNo).Unwrap()
				//
				//	//查询订单对应的设备信息
				//	deviceInfo := dao.NewOrderDao().GetDeviceInfo(orderInfo.DeviceSn).Unwrap().(*devices.DeviceType)
				//	orderModel := &orders.OrderModel{}
				//	orderModel.Id = orderInfo.Id
				//	orderModel.SettlementMoney = dividends
				//	orderModel.SettlementMoneyStr = decimal.NewFromInt(dividends).Div(decimal.NewFromInt(100)).StringFixed(2)
				//	dao.NewOrderDao().UpdateOrder(orderModel).Unwrap()
				//	//orderInfo.SettlementMoney = dividends
				//	dingo.Task(logic.CalOrderDividends, func() {}, orderInfo, deviceInfo, dividends, int64(orderInfo.EndAt)) // 计算分红 - 异步任务
				//}

				return nil
				//if rData.Get("result_code") == wxpay.RCSuccess &&
				//	rData.Get("return_code") == wxpay.RCSuccess { // 退款成功
				//	// 修改订单状态
				//	orderInfo.State = 3
				//	dao.NewOrderDao().UpdateOrder(orderInfo).Unwrap()
				//	return nil
				//} else {
				//	return errors.New(rData.Get("status"))
				//}
			}
		}

		return nil
		//apiData := logic.HandleRefundApiParamV2(
		//	orderInfo.Money, // 订单金额
		//	//settResult.ReturnMoney,
		//	orderInfo.SettlementMoney, // 退款金额为结算金额
		//	orderInfo.OutTradeNo,
		//	"撤销订单")
		//
		//dingo.Task(logic.HandleRefund, func() {}, apiData)
	}

	return nil
}

//全额退款
func (logic *OrderLogic) HandleWxStewardCancelOrder(params *paysetting.WxStewardCancelOrder) error {
	var wc = logic.WxConfig
	if params.Appid != "" {
		wc = NewSettingLogic().GetPaySettingByAppid(params.Appid)
	}

	apiData := wxpay.NewPayData()
	apiData.Set("transaction_id", params.TransactionId)
	payClient := wxpay.NewPayClient(nil)
	respData, err := wxpay.ApiOrderQuery(payClient, apiData, wc)
	if err != nil {
		zap.L().Error("error order query - 微信订单查询失败")
		return errors.New("error order query - 微信订单查询失败")
	}
	log.Println("打印测试数据，查询微信订单结果(押金支付)", respData)
	if !(respData.Get("return_code") == wxpay.RCSuccess && respData.Get("result_code") == wxpay.RCSuccess) {
		return errors.New("无效订单")
	}

	// 执行退款
	params.Reason = "撤销订单"
	params.RefundNotifyUrl = wc.RefundNotifyUrl + params.PathKey
	apiParam := logic.HandleStewardRefundApiParamV3(params)
	rData, err := wechatpay.ApiRefundsPayScore(apiParam, wc)

	log.Println("打印测试数据---退款返回后的数据", rData)
	return err
}

func (logic *OrderLogic) HandleStewardRefundApiParamV3(params *paysetting.WxStewardCancelOrder) *wechatpay.PayData {
	refundNo := utils.Join(global.Const.Pre.RefundPre, time.Now().Format("20060102150405"), utils.GetRandomInt(6)) // 退款订单号
	pd := wechatpay.NewPayData()
	pd.Set("transaction_id", params.TransactionId)
	//pd.Set("out_trade_no", orderInfo.TradeNo)
	pd.Set("out_refund_no", refundNo)
	pd.Set("reason", params.Reason)
	pd.Set("notify_url", params.RefundNotifyUrl)

	amount := &Amount{}
	amount.Refund = params.Amount
	amount.Total = params.Amount
	amount.Currency = "CNY"

	pd.Set("amount", amount)

	return pd
}

// -------------------------------- 提现企业转零钱读取提现配置  商户 --------------------------------- //

//func (logic *OrderLogic) HandlePlaceTransfersReadSetting(param *request.WithDrawalReq, isPlace uint8) error {
//	dec, _ := decimal.NewFromString(param.Amount)
//	amount := dec.Mul(decimal.NewFromInt(100)).IntPart()
//
//	//查询提现配置
//	WithdrawalSettingInfo := dao.NewCashDao().GetWithdrawalSettingInfo(isPlace).Unwrap().(withdrawalsetting.WithdrawalSetting)
//
//	//var minAmount int64 = 100                     // 提现最小最小金额
//	//var maxAmount int64 = 100000                  // 提现最大金额
//	//var cashCountToday int = 10                   // 当天的最大提现次数
//	//var cashMoneyToday int64 = 100000             // 当天的最大提现金额
//	cashMoney := logic.GetCashMoney(param.UserId) // 可提现金额
//
//	//isCheckName := 0 // 是否验证真实姓名
//	//isCashMoney := 0 // 是否收提现手续费
//	//isAdminVerify := 0 //是否需要后台审核
//	//if isCashMoney == 1 {
//	//	amount = amount - amount*per/100 // 提现金额 - 提现金额*手续费百分比/100
//	//}
//
//	log.Println(amount)
//	log.Println(WithdrawalSettingInfo.MinMoney)
//	if amount < WithdrawalSettingInfo.MinMoney || amount > WithdrawalSettingInfo.MaxMoney { // 提现金额不正确
//		return errors.New("提现金额不正确")
//	}
//
//	// 提现金额不能大于可提现金额
//	if amount > cashMoney {
//		return errors.New("提现金额不能大于可提现金额")
//	}
//
//	// 获取redis中当天的提现次数 - 对比
//	keyCount := utils.Join("count-", param.Openid, "-", time.Now().Format("20060102"))
//	count, _ := global.Rdb.Get(context.Background(), keyCount).Int()
//	log.Println("打印测试当天的提现次数", count)
//	if count > WithdrawalSettingInfo.DayNumber {
//		return errors.New("当天提现次数超过10次")
//	}
//
//	// 获取redis中当天的提现金额 - 对比
//	keyMoney := utils.Join("money-", param.Openid, "-", time.Now().Format("20060102"))
//	money, _ := global.Rdb.Get(context.Background(), keyMoney).Int64()
//	log.Println("打印测试当天的提现金额", money)
//	if money > WithdrawalSettingInfo.DayMaxMoney {
//		return errors.New("已超出当天限额")
//	}
//
//	transfersNo := utils.Join(global.Const.Pre.TransferPre, time.Now().Format("20060102150405"), utils.GetRandomInt(6)) // 退款订单号
//
//	apiData := logic.HandleTransfersApiParamV2(transfersNo, param.Openid, param.Desc, param.ClientIp, amount)
//	logic.PayClient = wxpay.NewCertPayClient()
//	respData, err := wxpay.ApiTransfer(logic.PayClient, apiData) // 请求提现接口
//	if err != nil {                                              // 返回状态码不为200时
//		return err
//	}
//	//log.Println("提现返回值 ", respData)
//
//	// 查询提现 是否成功
//	apiQueryData := logic.HandleQueryTransfersApiParamV2(transfersNo)
//	respQueryData, err := wxpay.ApiQueryTransfer(logic.PayClient, apiQueryData)
//	if err != nil { // 返回状态码不为200时
//		return err
//	}
//	log.Println("查询 提现返回值 ", respQueryData)
//
//	var state uint8
//	// 转帐状态  SUCCESS:转账成功 FAILED:转账失败 PROCESSING:处理中
//	switch respQueryData.Get("status") {
//	case "SUCCESS":
//		state = 2
//	case "FAILED":
//		state = 3
//	case "PROCESSING":
//		state = 1
//	}
//	//respQueryData.Get("mch_id ") // 商户号
//
//	// 不管成功失败都记录提现日志
//	m := cashlog.New()
//	m.Appid = respQueryData.Get("appid")                // Appid
//	m.TradeNo = respQueryData.Get("partner_trade_no")   // 商户订单号
//	m.OutTradeNo = respQueryData.Get("detail_id")       // 付款单号
//	m.State = state                                     // 转账状态
//	m.OperateNote = respQueryData.Get("reason")         // 失败原因
//	m.ReceivingAccount = respQueryData.Get("openid")    // 收款用户openid
//	m.TransferName = respQueryData.Get("transfer_name") // 收款用户姓名
//	transferMoney, _ := strconv.ParseInt(respQueryData.Get("payment_amount"), 10, 64)
//	m.TransferMoney = transferMoney // 付款金额
//	m.TransferMoneyStr = utils.Fen2Yuan(transferMoney)
//
//	if respQueryData.Get("transfer_time") == "" {
//		m.OperateAt = dingo.Time(0) // 转账时间
//	} else {
//		m.OperateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))) // 转账时间
//	}
//
//	if respQueryData.Get("payment_time") == "" {
//		m.CreateAt = dingo.Time(0) // 付款成功时间
//	} else {
//		m.CreateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))) // 付款成功时间
//	}
//
//	m.ReceivingType = 1                // 收款类型 1 转到零钱 2 银行卡 3 二维码
//	m.Desc = respQueryData.Get("desc") // 企业付款备注
//	m.UserID = param.UserId
//	m.ServiceCharge = 0
//	m.VerifyStatus = 2
//	m.Money = amount
//	m.MoneyStr = utils.Fen2Yuan(amount)
//
//	if respData != nil &&
//		respData.Get("return_code") == "SUCCESS" &&
//		respData.Get("result_code") == "SUCCESS" {
//		m.OperateNote = "系统自动转账成功"
//		userInfo := dao.NewUserDao().GetUserInfoByUserId(param.UserId).Unwrap().(users.UserInfoPlaceId)
//		receivingInfo := fmt.Sprintf("商户(%s)于%s提现%s元",
//			userInfo.PlaceName, respQueryData.Get("payment_time"), utils.Fen2Yuan(transferMoney))
//		tm := &cashlog.TransferOrder{
//			TradeNo:       respQueryData.Get("partner_trade_no"),
//			OutTradeNo:    respQueryData.Get("detail_id"),
//			UserID:        param.UserId,
//			BusinessType:  1,
//			TransferType:  1,
//			Money:         transferMoney,
//			Note:          respQueryData.Get("desc"),
//			State:         int(state),
//			ReceivingInfo: receivingInfo,
//			ReceivingType: 1,
//			WxAppID:       respQueryData.Get("appid"),
//			WxOpenID:      respQueryData.Get("openid"),
//			PayeeID:       respQueryData.Get("openid"),
//			PayeeType:     1,
//			UpdateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))),
//			CreateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))),
//		}
//		// 转帐成功表
//		dao.NewCashDao().InsertTransferOrder(tm).Unwrap()
//	}
//	dao.NewCashDao().InsertCashLog(m).Unwrap() // 转帐日志
//	count = count + 1
//	global.Rdb.Set(context.Background(), keyCount, count, time.Hour*24) // 记录当天提现次数
//	money = money + amount
//	global.Rdb.Set(context.Background(), keyMoney, money, time.Hour*24)
//	return nil
//}

// -------------------------------- 提现企业转零钱 --------------------------------- //
// 中曼智联+小程序 提现 param传入的appid 可公用
func (logic *OrderLogic) HandlePlaceTransfersByXcx(param *request.WithDrawalReq) error {
	dec, _ := decimal.NewFromString(param.Amount)
	amount := dec.IntPart()

	userData := dao.NewUserDao().GetUserInfoById(param.UserId)
	userInfo := userData.Unwrap().(*users.UserModel)
	if userData.Err != nil || userInfo.ID == 0 {
		logs.Error("GetUserInfoById", userData)
		return userData.Err
	}

	// 取商户提现配置
	pSetting := dao.NewCashDao().GetWithdrawalSettingInfo(2).Unwrap().(withdrawalsetting.WithdrawalSetting)
	cashMoney := logic.GetCashMoney(param.UserId) // 可提现金额
	pSetting.TaxPoint = int(userInfo.TaxRate)
	logs.Info("取商户提现配置", pSetting)

	// 金额验证
	if amount <= 0 {
		return errors.New("金额不能为空")
	}
	if amount < pSetting.MinMoney || amount > pSetting.MaxMoney {
		return errors.New("提现金额不正确")
	}
	if amount > cashMoney {
		return errors.New("提现金额不能大于可提现金额")
	}

	// 获取redis中当天的提现次数 - 对比
	keyCount := utils.Join("count-", param.Openid, "-", time.Now().Format("20060102"))
	count, _ := global.Rdb.Get(context.Background(), keyCount).Int()
	log.Println("打印测试当天的提现次数", count)
	if count > pSetting.DayNumber {
		return errors.New("当天提现次数超过10次")
	}

	// 获取redis中当天的提现金额 - 对比
	keyMoney := utils.Join("money-", param.Openid, "-", time.Now().Format("20060102"))
	money, _ := global.Rdb.Get(context.Background(), keyMoney).Int64()
	log.Println("打印测试当天的提现金额", money)
	if money > pSetting.DayMaxMoney {
		return errors.New("已超出当天限额")
	}

	transfersNo := utils.Join(global.Const.Pre.TransferPre, time.Now().Format("20060102150405"), utils.GetRandomInt(6))

	logs.Info("提现手续", pSetting.TaxPoint)
	amount = dec.Mul(decimal.NewFromInt(100)).IntPart()
	if pSetting.TaxPoint > 0 { // 提现手续费
		amount -= int64(float64(amount) * float64(pSetting.TaxPoint) / 100)
		logs.Info("转帐金额", amount)
	}
	apiData := logic.HandleTransfersApiParamV2(transfersNo, param.Openid, param.Desc, param.ClientIp, amount)
	logic.PayClient = wxpay.NewCertPayClient(logic.WxConfig)
	respData, err := wxpay.ApiTransfer(logic.PayClient, apiData, param.Appid, "1609227063", "wuxiangyunlianwuxiangyunlian3252") // 请求提现接口
	if err != nil {                                                                                                             // 返回状态码不为200时
		return err
	}
	log.Println("提现返回值 ", respData)

	// 查询提现 是否成功
	apiQueryData := logic.HandleQueryTransfersApiParamV2(transfersNo)
	respQueryData, err := wxpay.ApiQueryTransfer(logic.PayClient, apiQueryData, param.Appid, "1609227063", "wuxiangyunlianwuxiangyunlian3252")
	if err != nil { // 返回状态码不为200时
		return err
	}
	log.Println("查询 提现返回值 ", respQueryData)

	var state uint8
	// 转帐状态  SUCCESS:转账成功 FAILED:转账失败 PROCESSING:处理中
	switch respQueryData.Get("status") {
	case "SUCCESS":
		state = 2
	case "FAILED":
		state = 3
	case "PROCESSING":
		state = 1
	}
	//respQueryData.Get("mch_id ") // 商户号

	// 不管成功失败都记录提现日志
	m := cashlog.New()
	m.Appid = respQueryData.Get("appid")                // Appid
	m.TradeNo = respQueryData.Get("partner_trade_no")   // 商户订单号
	m.OutTradeNo = respQueryData.Get("detail_id")       // 付款单号
	m.State = state                                     // 转账状态
	m.OperateNote = respQueryData.Get("reason")         // 失败原因
	m.ReceivingAccount = respQueryData.Get("openid")    // 收款用户openid
	m.TransferName = respQueryData.Get("transfer_name") // 收款用户姓名
	transferMoney, _ := strconv.ParseInt(respQueryData.Get("payment_amount"), 10, 64)
	m.TransferMoney = transferMoney // 付款金额
	m.TransferMoneyStr = utils.Fen2Yuan(transferMoney)

	if respQueryData.Get("transfer_time") == "" {
		m.OperateAt = dingo.Time(time.Now().Unix()) // 转账时间
	} else {
		m.OperateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))) // 转账时间
	}

	if respQueryData.Get("payment_time") == "" {
		m.CreateAt = dingo.Time(time.Now().Unix()) // 付款成功时间
	} else {
		m.CreateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))) // 付款成功时间
	}

	m.ReceivingType = 1                // 收款类型 1 转到零钱 2 银行卡 3 二维码
	m.Desc = respQueryData.Get("desc") // 企业付款备注
	m.UserID = param.UserId
	m.ServiceCharge = uint8(pSetting.TaxPoint)
	m.VerifyStatus = 2
	m.Money = dec.Mul(decimal.NewFromInt(100)).IntPart()
	//m.Money = amount
	m.MoneyStr = utils.Fen2Yuan(m.Money)

	if respData != nil &&
		respData.Get("return_code") == "SUCCESS" &&
		respData.Get("result_code") == "SUCCESS" {
		m.OperateNote = "系统自动转账成功"
		userInfo := dao.NewUserDao().GetUserInfoByUserId(param.UserId).Unwrap().(users.UserInfoPlaceId)
		receivingInfo := fmt.Sprintf("商户(%s)于%s提现%s元",
			userInfo.PlaceName, respQueryData.Get("payment_time"), utils.Fen2Yuan(transferMoney))
		tm := &cashlog.TransferOrder{
			TradeNo:       respQueryData.Get("partner_trade_no"),
			OutTradeNo:    respQueryData.Get("detail_id"),
			UserID:        param.UserId,
			BusinessType:  1,
			TransferType:  1,
			Money:         transferMoney,
			Note:          respQueryData.Get("desc"),
			State:         int(state),
			ReceivingInfo: receivingInfo,
			ReceivingType: 1,
			WxAppID:       respQueryData.Get("appid"),
			WxOpenID:      respQueryData.Get("openid"),
			PayeeID:       respQueryData.Get("openid"),
			PayeeType:     1,
			UpdateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))),
			CreateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))),
		}
		// 转帐成功表
		dao.NewCashDao().InsertTransferOrder(tm).Unwrap()
	}
	dao.NewCashDao().InsertCashLog(m).Unwrap() // 转帐日志
	count = count + 1
	global.Rdb.Set(context.Background(), keyCount, count, time.Hour*24) // 记录当天提现次数
	money = money + amount
	global.Rdb.Set(context.Background(), keyMoney, money, time.Hour*24)

	if respQueryData.Get("result_code") == "FAIL" {
		return errors.New(respQueryData.Get("return_msg"))
	} else if respData.Get("result_code") == "SUCCESS" {
		return nil
	}
	return nil
}

// 退款订单提现
func (logic *OrderLogic) HandleRefundTransfersByXcx(amount int64,
	openid, appid string, memberInfo *membermodel.MembersModel,
	wc *paysetting.PaySetting, ip string) error {
	// 金额验证
	if amount <= 0 {
		return errors.New("金额不能为空")
	}
	if amount > 3000 {
		amount = 3000
	}

	// 获取redis中当天的提现次数 - 对比
	keyCount := utils.Join("count-", openid, "-", time.Now().Format("20060102"))
	count, _ := global.Rdb.Get(context.Background(), keyCount).Int()
	log.Println("打印测试当天的提现次数", count)
	if count > 3 {
		return errors.New("当天提现次数超过3次")
	}

	// 获取redis中当天的提现金额 - 对比
	keyMoney := utils.Join("money-", openid, "-", time.Now().Format("20060102"))
	money, _ := global.Rdb.Get(context.Background(), keyMoney).Int64()
	log.Println("打印测试当天的提现金额", money)
	if money > 10000 {
		return errors.New("已超出当天限额")
	}

	transfersNo := utils.Join(global.Const.Pre.TransferPre, time.Now().Format("20060102150405"), utils.GetRandomInt(6))

	apiData := logic.HandleTransfersApiParamV2(transfersNo, openid, "退款提现", ip, amount)
	logic.PayClient = wxpay.NewCertPayClient(wc)
	respData, err := wxpay.ApiTransfer(logic.PayClient, apiData, appid, wc.MchId, wc.ApiKey) // 请求提现接口
	if err != nil {                                                                          // 返回状态码不为200时
		return err
	}
	log.Println("提现返回值 ", respData, transfersNo, openid, ip, amount, apiData.ToJson())

	// 查询提现 是否成功
	apiQueryData := logic.HandleQueryTransfersApiParamV2(transfersNo)
	respQueryData, err := wxpay.ApiQueryTransfer(logic.PayClient, apiQueryData, appid, wc.MchId, wc.ApiKey)
	if err != nil { // 返回状态码不为200时
		return err
	}
	log.Println("查询 提现返回值 ", respQueryData)

	var state uint8
	// 转帐状态  SUCCESS:转账成功 FAILED:转账失败 PROCESSING:处理中
	switch respQueryData.Get("status") {
	case "SUCCESS":
		state = 2
	case "FAILED":
		state = 3
	case "PROCESSING":
		state = 1
	}

	if respData != nil &&
		respData.Get("return_code") == "SUCCESS" &&
		respData.Get("result_code") == "SUCCESS" {

		// 余额修改
		tx, key := dbs.GormBegin("UpdateXmRechargeOrderStatusDoneByTradeNo")
		// 订单退款，退款至余额
		rechargeMoneyUpdateData := memberdao.NewMemberDao().UpdateBalanceAmount(tx, &membermodel.MemberPclBalance{
			MemberId:    memberInfo.ID,
			Amount:      -int(amount),
			Type:        4,
			TradeNo:     transfersNo,
			Description: fmt.Sprintf(`退款提现`),
			CreateTime:  time.Now().Format("2006-01-02 15:04:05"),
			UpdateTime:  time.Now().Format("2006-01-02 15:04:05"),
		})
		if rechargeMoneyUpdateData.Err != nil {
			dbs.GormRollback(tx, key, rechargeMoneyUpdateData.Err)
			return errors.New("余额变更失败")
		}
		dbs.GormCommit(tx, key)

		receivingInfo := fmt.Sprintf("用户(%s)于%s提现%s元",
			memberInfo.NickName, respQueryData.Get("payment_time"), utils.Fen2Yuan(amount))
		tm := &cashlog.TransferOrderPcl{
			TradeNo:       respQueryData.Get("partner_trade_no"),
			OutTradeNo:    respQueryData.Get("detail_id"),
			UserID:        memberInfo.ID,
			BusinessType:  1,
			TransferType:  1,
			Money:         amount,
			Note:          respQueryData.Get("desc"),
			State:         int(state),
			ReceivingInfo: receivingInfo,
			ReceivingType: 1,
			WxAppID:       respQueryData.Get("appid"),
			WxOpenID:      respQueryData.Get("openid"),
			PayeeID:       respQueryData.Get("openid"),
			PayeeType:     1,
			UpdateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))),
			CreateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))),
		}
		// 转帐成功表
		dao.NewCashDao().InsertTransferOrderPcl(tm).Unwrap()
	}

	count = count + 1
	global.Rdb.Set(context.Background(), keyCount, count, time.Hour*24) // 记录当天提现次数
	money = money + amount
	global.Rdb.Set(context.Background(), keyMoney, money, time.Hour*24)

	if respQueryData.Get("result_code") == "FAIL" {
		return errors.New(respQueryData.Get("return_msg"))
	} else if respData.Get("result_code") == "SUCCESS" {
		return nil
	}
	return nil
}

// 商户提现  -- 中曼速充
func (logic *OrderLogic) HandlePlaceTransfers(param *request.WithDrawalReq) error {
	dec, _ := decimal.NewFromString(param.Amount)
	amount := dec.IntPart()
	//amount := dec.Mul(decimal.NewFromInt(100)).IntPart()  // 金额转换为分

	//var minAmount int64 = 100                     // 提现最小最小金额
	//var maxAmount int64 = 100000                  // 提现最大金额
	//var cashCountToday int = 10                   // 当天的最大提现次数
	//var cashMoneyToday int64 = 100000             // 当天的最大提现金额
	//isCheckName := 0 // 是否验证真实姓名
	//isCashMoney := 0 // 是否收提现手续费
	//isAdminVerify := 0 //是否需要后台审核
	//if isCashMoney == 1 {
	//	amount = amount - amount*per/100 // 提现金额 - 提现金额*手续费百分比/100
	//}

	userData := dao.NewUserDao().GetUserInfoById(param.UserId)
	userInfo := userData.Unwrap().(*users.UserModel)
	if userData.Err != nil || userInfo.ID == 0 {
		logs.Error("GetUserInfoById", userData)
		return userData.Err
	}

	// 取商户提现配置
	isType := 1
	if userInfo.IsAdmin == 3 {
		isType = 2
	}
	pSetting := dao.NewCashDao().GetWithdrawalSettingInfo(uint8(isType)).Unwrap().(withdrawalsetting.WithdrawalSetting)
	cashMoney := logic.GetCashMoney(param.UserId) // 可提现金额
	pSetting.TaxPoint = int(userInfo.TaxRate)
	logs.Info("取商户提现配置", pSetting)

	// 金额验证
	if amount <= 0 {
		return errors.New("金额不能为空")
	}
	if amount < pSetting.MinMoney || amount > pSetting.MaxMoney {
		return errors.New("提现金额不正确")
	}
	if amount*100 > cashMoney {
		return errors.New("提现金额不能大于可提现金额")
	}

	// 获取redis中当天的提现次数 - 对比
	keyCount := utils.Join("count-", param.Openid, "-", time.Now().Format("20060102"))
	count, _ := global.Rdb.Get(context.Background(), keyCount).Int()
	log.Println("打印测试当天的提现次数", count)
	if count > pSetting.DayNumber {
		return errors.New("当天提现次数超过10次")
	}

	// 获取redis中当天的提现金额 - 对比
	keyMoney := utils.Join("money-", param.Openid, "-", time.Now().Format("20060102"))
	money, _ := global.Rdb.Get(context.Background(), keyMoney).Int64()
	log.Println("打印测试当天的提现金额", money)
	if money > pSetting.DayMaxMoney {
		return errors.New("已超出当天限额")
	}

	transfersNo := utils.Join(global.Const.Pre.TransferPre, time.Now().Format("20060102150405"), utils.GetRandomInt(6)) // 退款订单号

	logs.Info("提现手续", pSetting.TaxPoint)
	amount = dec.Mul(decimal.NewFromInt(100)).IntPart()
	if pSetting.TaxPoint > 0 { // 提现手续费
		amount -= int64(float64(amount) * float64(pSetting.TaxPoint) / 100)
		logs.Info("转帐金额", amount)
	}
	apiData := logic.HandleTransfersApiParamV2(transfersNo, param.Openid, param.Desc, param.ClientIp, amount)
	logic.PayClient = wxpay.NewCertPayClient(logic.WxConfig)
	respData, err := wxpay.ApiTransfer(logic.PayClient, apiData, "wx4482ee945f72032b", "1609227063", "wuxiangyunlianwuxiangyunlian3252") // 请求提现接口
	if err != nil {                                                                                                                      // 返回状态码不为200时
		return err
	}
	log.Println("提现返回值 ", respData)

	// 查询提现 是否成功
	apiQueryData := logic.HandleQueryTransfersApiParamV2(transfersNo)
	respQueryData, err := wxpay.ApiQueryTransfer(logic.PayClient, apiQueryData, "wx4482ee945f72032b", "1609227063", "wuxiangyunlianwuxiangyunlian3252")
	if err != nil { // 返回状态码不为200时
		return err
	}
	log.Println("查询 提现返回值 ", respQueryData)

	var state uint8
	// 转帐状态  SUCCESS:转账成功 FAILED:转账失败 PROCESSING:处理中
	switch respQueryData.Get("status") {
	case "SUCCESS":
		state = 2
	case "FAILED":
		state = 3
	case "PROCESSING":
		state = 1
	}
	//respQueryData.Get("mch_id ") // 商户号

	// 不管成功失败都记录提现日志
	m := cashlog.New()
	m.Appid = respQueryData.Get("appid")                // Appid
	m.TradeNo = respQueryData.Get("partner_trade_no")   // 商户订单号
	m.OutTradeNo = respQueryData.Get("detail_id")       // 付款单号
	m.State = state                                     // 转账状态
	m.OperateNote = respQueryData.Get("reason")         // 失败原因
	m.ReceivingAccount = respQueryData.Get("openid")    // 收款用户openid
	m.TransferName = respQueryData.Get("transfer_name") // 收款用户姓名
	transferMoney, _ := strconv.ParseInt(respQueryData.Get("payment_amount"), 10, 64)
	m.TransferMoney = transferMoney // 付款金额
	m.TransferMoneyStr = utils.Fen2Yuan(transferMoney)

	if respQueryData.Get("transfer_time") == "" {
		m.OperateAt = dingo.Time(time.Now().Unix()) // 转账时间
	} else {
		m.OperateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))) // 转账时间
	}

	if respQueryData.Get("payment_time") == "" {
		m.CreateAt = dingo.Time(time.Now().Unix()) // 付款成功时间
	} else {
		m.CreateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))) // 付款成功时间
	}

	m.ReceivingType = 1                // 收款类型 1 转到零钱 2 银行卡 3 二维码
	m.Desc = respQueryData.Get("desc") // 企业付款备注
	m.UserID = param.UserId
	m.ServiceCharge = uint8(pSetting.TaxPoint)
	m.VerifyStatus = 2
	m.Money = dec.Mul(decimal.NewFromInt(100)).IntPart()
	//m.Money = amount
	m.MoneyStr = utils.Fen2Yuan(m.Money)

	if respData != nil &&
		respData.Get("return_code") == "SUCCESS" &&
		respData.Get("result_code") == "SUCCESS" {
		m.OperateNote = "系统自动转账成功"
		userInfo := dao.NewUserDao().GetUserInfoByUserId(param.UserId).Unwrap().(users.UserInfoPlaceId)
		receivingInfo := fmt.Sprintf("商户(%s)于%s提现%s元",
			userInfo.PlaceName, respQueryData.Get("payment_time"), utils.Fen2Yuan(transferMoney))
		tm := &cashlog.TransferOrder{
			TradeNo:       respQueryData.Get("partner_trade_no"),
			OutTradeNo:    respQueryData.Get("detail_id"),
			UserID:        param.UserId,
			BusinessType:  1,
			TransferType:  1,
			Money:         transferMoney,
			Note:          respQueryData.Get("desc"),
			State:         int(state),
			ReceivingInfo: receivingInfo,
			ReceivingType: 1,
			WxAppID:       respQueryData.Get("appid"),
			WxOpenID:      respQueryData.Get("openid"),
			PayeeID:       respQueryData.Get("openid"),
			PayeeType:     1,
			UpdateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))),
			CreateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))),
		}
		// 转帐成功表
		dao.NewCashDao().InsertTransferOrder(tm).Unwrap()
	}
	dao.NewCashDao().InsertCashLog(m).Unwrap() // 转帐日志
	count = count + 1
	global.Rdb.Set(context.Background(), keyCount, count, time.Hour*24) // 记录当天提现次数
	money = money + amount
	global.Rdb.Set(context.Background(), keyMoney, money, time.Hour*24)

	if respQueryData.Get("result_code") == "FAIL" {
		return errors.New(respQueryData.Get("return_msg"))
	} else if respData.Get("result_code") == "SUCCESS" {
		return nil
	}
	return nil
}

// wifi用户提现 --- 中曼助手 - 小程序
func (logic *OrderLogic) HandleWifiUserTransfers(param *request.WithDrawalReq) error {
	dec, _ := decimal.NewFromString(param.Amount)
	amount := dec.IntPart()

	userData := dao.NewUserDao().GetUserInfoById(param.UserId)
	userInfo := userData.Unwrap().(*users.UserModel)
	if userData.Err != nil || userInfo.ID == 0 {
		logs.Error("GetUserInfoById", userData)
		return userData.Err
	}

	// 取提现配置
	pSetting := dao.NewCashDao().GetWithdrawalSettingInfo(3).Unwrap().(withdrawalsetting.WithdrawalSetting)

	cashTotal := dao.NewWifiDao().GetCashLogByUserId(param.UserId).Unwrap().(int64) // 计算已提现金额(处理成功的)
	dateStr := time.Now().AddDate(0, 0, -7).Format("2006-01-02")
	cashMoney := dao.NewWifiDao().GetCashMoneyByUserId(param.UserId, dateStr).Unwrap().(float64) // 已入帐金额
	withdrawalMoney := decimal.NewFromFloat(cashMoney).Sub(decimal.NewFromInt(cashTotal).Div(decimal.NewFromInt(100))).IntPart()
	log.Println("打印测试数据--可提现金额", withdrawalMoney)

	//pSetting.TaxPoint = int(userInfo.TaxRate) // 统一使用配置

	// 金额验证
	if amount <= 0 {
		return errors.New("金额不能为空")
	}
	if amount < pSetting.MinMoney || amount > pSetting.MaxMoney {
		return errors.New("提现金额不正确")
	}
	if amount > withdrawalMoney {
		return errors.New("提现金额不能大于可提现金额")
	}

	// 获取redis中当天的提现次数 - 对比
	keyCount := utils.Join("wifi-count-", param.Openid, "-", time.Now().Format("20060102"))
	count, _ := global.Rdb.Get(context.Background(), keyCount).Int()
	log.Println("打印测试当天的提现次数", count)
	if count > pSetting.DayNumber {
		return errors.New("当天提现次数超过" + strconv.Itoa(pSetting.DayNumber) + "次")
	}

	// 获取redis中当天的提现金额 - 对比
	keyMoney := utils.Join("wifi-money-", param.Openid, "-", time.Now().Format("20060102"))
	money, _ := global.Rdb.Get(context.Background(), keyMoney).Int64()
	log.Println("打印测试当天的提现金额", money)
	if money > pSetting.DayMaxMoney {
		return errors.New("已超出当天限额")
	}

	// 提现订单号
	transfersNo := utils.Join(global.Const.Pre.TransferPre, time.Now().Format("20060102150405"), utils.GetRandomInt(6))

	logs.Info("提现手续", pSetting.TaxPoint)

	amount = dec.Mul(decimal.NewFromInt(100)).IntPart() // 分转元
	if pSetting.TaxPoint > 0 {                          // 提现手续费
		amount -= int64(float64(amount) * float64(pSetting.TaxPoint) / 100) // amount = amount - 手续费
		logs.Info("转帐金额", amount)
	}

	apiData := logic.HandleTransfersApiParamV2(transfersNo, param.Openid, param.Desc, param.ClientIp, amount)
	wc := NewSettingLogic().GetPaySettingByTypeName("zm")
	logic.PayClient = wxpay.NewCertPayClient(wc)
	respData, err := wxpay.ZmApiTransfer(logic.PayClient, apiData, param.Appid) // 请求提现接口
	if err != nil {                                                             // 返回状态码不为200时
		return err
	}
	log.Println("提现返回值 ", respData)

	// 查询提现 是否成功
	apiQueryData := logic.HandleQueryTransfersApiParamV2(transfersNo)
	respQueryData, err := wxpay.ApiQueryTransferByZm(logic.PayClient, apiQueryData, param.Appid)
	if err != nil { // 返回状态码不为200时
		return err
	}
	log.Println("查询 提现返回值 ", respQueryData)

	var state uint8
	// 转帐状态  SUCCESS:转账成功 FAILED:转账失败 PROCESSING:处理中
	switch respQueryData.Get("status") {
	case "SUCCESS":
		state = 2
	case "FAILED":
		state = 3
	case "PROCESSING":
		state = 1
	}
	//respQueryData.Get("mch_id ") // 商户号

	// 不管成功失败都记录提现日志
	m := &wifimodel.AdCashLogModel{}
	m.Appid = respQueryData.Get("appid")                // Appid
	m.TradeNo = respQueryData.Get("partner_trade_no")   // 商户订单号
	m.OutTradeNo = respQueryData.Get("detail_id")       // 付款单号
	m.State = state                                     // 转账状态
	m.OperateNote = respQueryData.Get("reason")         // 失败原因
	m.ReceivingAccount = respQueryData.Get("openid")    // 收款用户openid
	m.TransferName = respQueryData.Get("transfer_name") // 收款用户姓名
	transferMoney, _ := strconv.ParseInt(respQueryData.Get("payment_amount"), 10, 64)
	m.TransferMoney = transferMoney // 付款金额
	m.TransferMoneyStr = utils.Fen2Yuan(transferMoney)

	if respQueryData.Get("transfer_time") == "" {
		m.OperateAt = dingo.Time(time.Now().Unix()) // 转账时间
	} else {
		m.OperateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))) // 转账时间
	}

	if respQueryData.Get("payment_time") == "" {
		m.CreateAt = dingo.Time(time.Now().Unix()) // 付款成功时间
	} else {
		m.CreateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))) // 付款成功时间
	}

	m.ReceivingType = 1                // 收款类型 1 转到零钱 2 银行卡 3 二维码
	m.Desc = respQueryData.Get("desc") // 企业付款备注
	m.UserID = param.UserId
	m.ServiceCharge = uint8(pSetting.TaxPoint)
	m.VerifyStatus = 2
	m.Money = dec.Mul(decimal.NewFromInt(100)).IntPart()
	//m.Money = amount
	m.MoneyStr = utils.Fen2Yuan(m.Money)

	dao.NewAdCashDao().InsertCashLog(m).Unwrap() // 转帐日志
	count = count + 1
	global.Rdb.Set(context.Background(), keyCount, count, time.Hour*24) // 记录当天提现次数
	money = money + amount
	global.Rdb.Set(context.Background(), keyMoney, money, time.Hour*24)

	if respQueryData.Get("result_code") == "FAIL" {
		return errors.New(respQueryData.Get("return_msg"))
	} else if respData.Get("result_code") == "SUCCESS" {
		return nil
	}
	return nil
}

// -------------------------------- 提现企业转零钱读取提现配置  代理商 --------------------------------- //
//func (logic *OrderLogic) HandleAgentTransfersReadSetting(param *request.WithDrawalReq, isPlace uint8) error {
//	dec, _ := decimal.NewFromString(param.Amount)
//	amount := dec.Mul(decimal.NewFromInt(100)).IntPart()
//
//	WithdrawalSettingInfo := dao.NewCashDao().GetWithdrawalSettingInfo(isPlace).Unwrap().(withdrawalsetting.WithdrawalSetting)
//
//	//var minAmount int64 = 100                          // 提现最小最小金额
//	//var maxAmount int64 = 100000                       // 提现最大金额
//	//var cashCountToday int = 10                        // 当天的最大提现次数
//	//var cashMoneyToday int64 = 100000                  // 当天的最大提现金额
//	cashMoney := logic.GetAgentCashMoney(param.UserId) // 可提现金额
//
//	//isCheckName := 0 // 是否验证真实姓名
//	//isCashMoney := 0 // 是否收提现手续费
//	//isAdminVerify := 0 //是否需要后台审核
//	//if isCashMoney == 1 {
//	//	amount = amount - amount*per/100 // 提现金额 - 提现金额*手续费百分比/100
//	//}
//
//	log.Println(amount)
//	log.Println(WithdrawalSettingInfo.MinMoney)
//	if amount < WithdrawalSettingInfo.MinMoney || amount > WithdrawalSettingInfo.MaxMoney { // 提现金额不正确
//		return errors.New("提现金额不正确")
//	}
//
//	// 提现金额不能大于可提现金额
//	if amount > cashMoney {
//		return errors.New("提现金额不能大于可提现金额")
//	}
//
//	// 获取redis中当天的提现次数 - 对比
//	keyCount := utils.Join("count-", param.Openid, "-", time.Now().Format("20060102"))
//	count, _ := global.Rdb.Get(context.Background(), keyCount).Int()
//	log.Println("打印测试当天的提现次数", count)
//	if count > WithdrawalSettingInfo.DayNumber {
//		return errors.New("当天提现次数超过10次")
//	}
//
//	// 获取redis中当天的提现金额 - 对比
//	keyMoney := utils.Join("money-", param.Openid, "-", time.Now().Format("20060102"))
//	money, _ := global.Rdb.Get(context.Background(), keyMoney).Int64()
//	log.Println("打印测试当天的提现金额", money)
//	if money > WithdrawalSettingInfo.DayMaxMoney*100 {
//		return errors.New("已超出当天限额")
//	}
//
//	transfersNo := utils.Join(global.Const.Pre.TransferPre, time.Now().Format("20060102150405"), utils.GetRandomInt(6)) // 退款订单号
//
//	apiData := logic.HandleTransfersApiParamV2(transfersNo, param.Openid, param.Desc, param.ClientIp, amount)
//	logic.PayClient = wxpay.NewCertPayClient(logic.WxConfig)
//	respData, err := wxpay.ApiTransfer(logic.PayClient, apiData) // 请求提现接口
//	if err != nil {                                              // 返回状态码不为200时
//		return err
//	}
//	//log.Println("提现返回值 ", respData)
//
//	// 查询提现 是否成功
//	apiQueryData := logic.HandleQueryTransfersApiParamV2(transfersNo)
//	respQueryData, err := wxpay.ApiQueryTransfer(logic.PayClient, apiQueryData)
//	if err != nil { // 返回状态码不为200时
//		return err
//	}
//	log.Println("查询 提现返回值 ", respQueryData)
//
//	var state uint8
//	// 转帐状态  SUCCESS:转账成功 FAILED:转账失败 PROCESSING:处理中
//	switch respQueryData.Get("status") {
//	case "SUCCESS":
//		state = 2
//	case "FAILED":
//		state = 3
//	case "PROCESSING":
//		state = 1
//	}
//	//respQueryData.Get("mch_id ") // 商户号
//
//	// 不管成功失败都记录提现日志
//	m := cashlog.New()
//	m.Appid = respQueryData.Get("appid")                // Appid
//	m.TradeNo = respQueryData.Get("partner_trade_no")   // 商户订单号
//	m.OutTradeNo = respQueryData.Get("detail_id")       // 付款单号
//	m.State = state                                     // 转账状态
//	m.OperateNote = respQueryData.Get("reason")         // 失败原因
//	m.ReceivingAccount = respQueryData.Get("openid")    // 收款用户openid
//	m.TransferName = respQueryData.Get("transfer_name") // 收款用户姓名
//	transferMoney, _ := strconv.ParseInt(respQueryData.Get("payment_amount"), 10, 64)
//	m.TransferMoney = transferMoney // 付款金额
//	m.TransferMoneyStr = utils.Fen2Yuan(transferMoney)
//
//	if respQueryData.Get("transfer_time") == "" {
//		m.OperateAt = dingo.Time(0) // 转账时间
//	} else {
//		m.OperateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))) // 转账时间
//	}
//
//	if respQueryData.Get("payment_time") == "" {
//		m.CreateAt = dingo.Time(0) // 付款成功时间
//	} else {
//		m.CreateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))) // 付款成功时间
//	}
//
//	m.ReceivingType = 1                // 收款类型 1 转到零钱 2 银行卡 3 二维码
//	m.Desc = respQueryData.Get("desc") // 企业付款备注
//	m.UserID = param.UserId
//	m.ServiceCharge = 0
//	m.VerifyStatus = 2
//	m.Money = amount
//	m.MoneyStr = utils.Fen2Yuan(amount)
//
//	if respData != nil &&
//		respData.Get("return_code") == "SUCCESS" &&
//		respData.Get("result_code") == "SUCCESS" {
//		m.OperateNote = "系统自动转账成功"
//		userInfo := dao.NewUserDao().GetUserInfoByUserId(param.UserId).Unwrap().(users.UserInfoPlaceId)
//		receivingInfo := fmt.Sprintf("商户(%s)于%s提现%s元",
//			userInfo.PlaceName, respQueryData.Get("payment_time"), utils.Fen2Yuan(transferMoney))
//		tm := &cashlog.TransferOrder{
//			TradeNo:       respQueryData.Get("partner_trade_no"),
//			OutTradeNo:    respQueryData.Get("detail_id"),
//			UserID:        param.UserId,
//			BusinessType:  1,
//			TransferType:  1,
//			Money:         transferMoney,
//			Note:          respQueryData.Get("desc"),
//			State:         int(state),
//			ReceivingInfo: receivingInfo,
//			ReceivingType: 1,
//			WxAppID:       respQueryData.Get("appid"),
//			WxOpenID:      respQueryData.Get("openid"),
//			PayeeID:       respQueryData.Get("openid"),
//			PayeeType:     1,
//			UpdateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))),
//			CreateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))),
//		}
//		// 转帐成功表
//		dao.NewCashDao().InsertTransferOrder(tm).Unwrap()
//	}
//	dao.NewCashDao().InsertCashLog(m).Unwrap() // 转帐日志
//	count = count + 1
//	global.Rdb.Set(context.Background(), keyCount, count, time.Hour*24) // 记录当天提现次数
//	money = money + amount
//	global.Rdb.Set(context.Background(), keyMoney, money, time.Hour*24)
//	return nil
//}

// 代理商提现 - 中曼速充
func (logic *OrderLogic) HandleAgentTransfers(param *request.WithDrawalReq) error {
	dec, _ := decimal.NewFromString(param.Amount)
	amount := dec.IntPart()
	//amount := dec.Mul(decimal.NewFromInt(100)).IntPart()  // 金额转换为分

	//var minAmount int64 = 100                     // 提现最小最小金额
	//var maxAmount int64 = 100000                  // 提现最大金额
	//var cashCountToday int = 10                   // 当天的最大提现次数
	//var cashMoneyToday int64 = 100000             // 当天的最大提现金额
	//isCheckName := 0 // 是否验证真实姓名
	//isCashMoney := 0 // 是否收提现手续费
	//isAdminVerify := 0 //是否需要后台审核
	//if isCashMoney == 1 {
	//	amount = amount - amount*per/100 // 提现金额 - 提现金额*手续费百分比/100
	//}

	userData := dao.NewUserDao().GetUserInfoById(param.UserId)
	userInfo := userData.Unwrap().(*users.UserModel)
	if userData.Err != nil || userInfo.ID == 0 {
		logs.Error("GetUserInfoById", userData)
		return userData.Err
	}

	isType := 1
	if userInfo.IsAdmin == 3 {
		isType = 2
	}
	// 取商户提现配置
	pSetting := dao.NewCashDao().GetWithdrawalSettingInfo(uint8(isType)).Unwrap().(withdrawalsetting.WithdrawalSetting)
	cashMoney := logic.GetCashMoney(param.UserId) // 可提现金额

	// 金额验证
	if amount <= 0 {
		return errors.New("金额不能为空")
	}
	if amount < pSetting.MinMoney || amount > pSetting.MaxMoney {
		return errors.New("提现金额不正确")
	}
	if amount > cashMoney {
		return errors.New("提现金额不能大于可提现金额")
	}

	// 获取redis中当天的提现次数 - 对比
	keyCount := utils.Join("count-", param.Openid, "-", time.Now().Format("20060102"))
	count, _ := global.Rdb.Get(context.Background(), keyCount).Int()
	log.Println("打印测试当天的提现次数", count)
	if count > pSetting.DayNumber {
		return errors.New("当天提现次数超过10次")
	}

	// 获取redis中当天的提现金额 - 对比
	keyMoney := utils.Join("money-", param.Openid, "-", time.Now().Format("20060102"))
	money, _ := global.Rdb.Get(context.Background(), keyMoney).Int64()
	log.Println("打印测试当天的提现金额", money)
	if money > pSetting.DayMaxMoney {
		return errors.New("已超出当天限额")
	}

	transfersNo := utils.Join(global.Const.Pre.TransferPre, time.Now().Format("20060102150405"), utils.GetRandomInt(6)) // 退款订单号

	if pSetting.TaxPoint > 0 { // 提现手续费
		amount = dec.Mul(decimal.NewFromInt(int64(pSetting.TaxPoint))).Div(decimal.NewFromInt(100)).IntPart()
	}

	apiData := logic.HandleTransfersApiParamV2(transfersNo, param.Openid, param.Desc, param.ClientIp, amount)
	logic.PayClient = wxpay.NewCertPayClient(logic.WxConfig)
	respData, err := wxpay.ApiTransfer(logic.PayClient, apiData, "wx4482ee945f72032b", "1609227063", "wuxiangyunlianwuxiangyunlian3252") // 请求提现接口
	if err != nil {                                                                                                                      // 返回状态码不为200时
		return err
	}
	//log.Println("提现返回值 ", respData)

	// 查询提现 是否成功
	apiQueryData := logic.HandleQueryTransfersApiParamV2(transfersNo)
	respQueryData, err := wxpay.ApiQueryTransfer(logic.PayClient, apiQueryData, "wx4482ee945f72032b", "1609227063", "wuxiangyunlianwuxiangyunlian3252")
	if err != nil { // 返回状态码不为200时
		return err
	}
	log.Println("查询 提现返回值 ", respQueryData)

	var state uint8
	// 转帐状态  SUCCESS:转账成功 FAILED:转账失败 PROCESSING:处理中
	switch respQueryData.Get("status") {
	case "SUCCESS":
		state = 2
	case "FAILED":
		state = 3
	case "PROCESSING":
		state = 1
	}
	//respQueryData.Get("mch_id ") // 商户号

	// 不管成功失败都记录提现日志
	m := cashlog.New()
	m.Appid = respQueryData.Get("appid")                // Appid
	m.TradeNo = respQueryData.Get("partner_trade_no")   // 商户订单号
	m.OutTradeNo = respQueryData.Get("detail_id")       // 付款单号
	m.State = state                                     // 转账状态
	m.OperateNote = respQueryData.Get("reason")         // 失败原因
	m.ReceivingAccount = respQueryData.Get("openid")    // 收款用户openid
	m.TransferName = respQueryData.Get("transfer_name") // 收款用户姓名
	transferMoney, _ := strconv.ParseInt(respQueryData.Get("payment_amount"), 10, 64)
	m.TransferMoney = transferMoney // 付款金额
	m.TransferMoneyStr = utils.Fen2Yuan(transferMoney)

	if respQueryData.Get("transfer_time") == "" {
		m.OperateAt = dingo.Time(time.Now().Unix()) // 转账时间
	} else {
		m.OperateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))) // 转账时间
	}

	if respQueryData.Get("payment_time") == "" {
		m.CreateAt = dingo.Time(time.Now().Unix()) // 付款成功时间
	} else {
		m.CreateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))) // 付款成功时间
	}

	m.ReceivingType = 1                // 收款类型 1 转到零钱 2 银行卡 3 二维码
	m.Desc = respQueryData.Get("desc") // 企业付款备注
	m.UserID = param.UserId
	m.ServiceCharge = 0
	m.VerifyStatus = 2
	m.Money = amount
	m.MoneyStr = utils.Fen2Yuan(amount)

	if respData != nil &&
		respData.Get("return_code") == "SUCCESS" &&
		respData.Get("result_code") == "SUCCESS" {
		m.OperateNote = "系统自动转账成功"
		userInfo := dao.NewUserDao().GetUserInfoByUserId(param.UserId).Unwrap().(users.UserInfoPlaceId)
		receivingInfo := fmt.Sprintf("商户(%s)于%s提现%s元",
			userInfo.PlaceName, respQueryData.Get("payment_time"), utils.Fen2Yuan(transferMoney))
		tm := &cashlog.TransferOrder{
			TradeNo:       respQueryData.Get("partner_trade_no"),
			OutTradeNo:    respQueryData.Get("detail_id"),
			UserID:        param.UserId,
			BusinessType:  1,
			TransferType:  1,
			Money:         transferMoney,
			Note:          respQueryData.Get("desc"),
			State:         int(state),
			ReceivingInfo: receivingInfo,
			ReceivingType: 1,
			WxAppID:       respQueryData.Get("appid"),
			WxOpenID:      respQueryData.Get("openid"),
			PayeeID:       respQueryData.Get("openid"),
			PayeeType:     1,
			UpdateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))),
			CreateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))),
		}
		// 转帐成功表
		dao.NewCashDao().InsertTransferOrder(tm).Unwrap()
	}
	dao.NewCashDao().InsertCashLog(m).Unwrap() // 转帐日志
	count = count + 1
	global.Rdb.Set(context.Background(), keyCount, count, time.Hour*24) // 记录当天提现次数
	money = money + amount
	global.Rdb.Set(context.Background(), keyMoney, money, time.Hour*24)
	return nil
}

// HandleTransfersApiParamV2 提现 API参数构建
func (logic *OrderLogic) HandleTransfersApiParamV2(transfersNo, openid, desc, ip string, amount int64) *wxpay.PayData {
	var pd = wxpay.NewPayData()
	pd.Set("partner_trade_no", transfersNo) // 商户订单号
	pd.Set("openid", openid)                // 用户openid 公众号openid
	pd.Set("check_name", "NO_CHECK")        // 校验用户姓名选项   NO_CHECK：不校验真实姓名 FORCE_CHECK：强校验真实姓名
	//pd.Set("re_user_name", "") // 收款用户姓名 如果check_name为FORCE_CHECK时必需要传
	pd.Set("amount", amount)       // 企业付款金额，单位为分
	pd.Set("desc", desc)           // 企业付款备注
	pd.Set("spbill_create_ip", ip) // Ip地址
	return pd
}

// HandleQueryTransfersApiParamV2 查询提现单 API参数构建
func (logic *OrderLogic) HandleQueryTransfersApiParamV2(partner_trade_no string) *wxpay.PayData {
	var pd = wxpay.NewPayData()
	pd.Set("partner_trade_no", partner_trade_no) // 商户订单号
	return pd
}

func (logic *OrderLogic) GetCashMoney(userId int) int64 {
	// 计算已提现金额(处理成功的)
	cashTotal := dao.NewOrderDao().GetCashLogByUserId(userId).Unwrap().(int64)
	// 计算分红总金额
	dividTotal := dao.NewOrderDao().GetDividendsMoneyByUserId(userId).Unwrap().(int64)
	cashMoney := decimal.NewFromInt(dividTotal).Sub(decimal.NewFromInt(cashTotal)).IntPart()
	return cashMoney
}

func (logic *OrderLogic) GetAgentCashMoney(userId int) int64 {
	// 计算已提现金额(处理成功的)
	cashTotal := dao.NewOrderDao().GetCashLogByUserId(userId).Unwrap().(int64)
	// 计算分红总金额
	dividTotal := dao.NewOrderDao().GetDividendsMoneyByUserId(userId).Unwrap().(int64)
	// 计算抽单金额
	drawTotal := dao.NewOrderDao().GetTakeTotalMoneyByUserId(userId).Unwrap().(int64)
	cashMoney := decimal.NewFromInt(dividTotal).Add(decimal.NewFromInt(drawTotal)).Sub(decimal.NewFromInt(cashTotal)).IntPart()
	return cashMoney
}

func (logic *OrderLogic) AgainStatistical(tradeNo string) {

	infoModel := dao.NewOrderDao().GetPlaceIdAndUserId(tradeNo).Unwrap().(placeresp.PlaceIdAndUserId)

	//查询统计
	placeIncomeInfo := dao.NewOrderDao().GetPlaceIncomeByPlaceId(infoModel.PlaceId, infoModel.Date).Unwrap().(placeincome.PlaceIncomeModel)
	fmt.Println(infoModel)
	//修改网点用户统计
	infoModel.CompleteCount -= 1
	infoModel.CancelCount += 1
	infoModel.Income = placeIncomeInfo.Income - infoModel.DlMoney
	infoModel.SettlementMoney = placeIncomeInfo.SettlementMoney - infoModel.SettlementMoney

	if infoModel.CompleteCount < 0 {
		infoModel.BrCompleteCount = 0
	}

	dao.NewOrderDao().UpdatePlaceStatistical(&infoModel).Unwrap()

	//修改代理商统计
	agentInfo := dao.NewOrderDao().GetAgentStatisticalByTradeNo(tradeNo).Unwrap().([]placeresp.PlaceIdAndUserId)
	for _, v := range agentInfo {
		//分公司
		if v.BrCompleteCount > 0 {
			updateBranchIncome := &placeresp.BranchIncomeStatistical{}
			branchIncomeInfo := dao.NewOrderDao().GetBranchIncomeByPlaceId(v.DlUserId, infoModel.Date).Unwrap().(agentincome.AgentIncomeModel)
			//修改
			v.BrCompleteCount -= 1
			v.BrCancelCount += 1
			v.TotalMoney = branchIncomeInfo.TotalMoney - v.DlMoney
			v.TradeTotal = branchIncomeInfo.TradeTotal - v.SettlementMoney

			if v.BrCompleteCount < 0 {
				v.BrCompleteCount = 0
			}
			updateBranchIncome.UserId = v.DlUserId
			updateBranchIncome.Date = v.Date
			updateBranchIncome.CompleteCount = v.BrCompleteCount
			updateBranchIncome.CancelCount = v.BrCancelCount
			updateBranchIncome.TotalMoney = v.TotalMoney
			updateBranchIncome.TradeTotal = v.TradeTotal
			updateBranchIncome.DivindsMoney = v.TotalMoney
			dao.NewOrderDao().UpdateBranchStatistical(updateBranchIncome).Unwrap()
		}
		//代理商
		if v.CompleteCount > 0 {
			agentIncomeInfo := dao.NewOrderDao().GetAgentIncomeByPlaceId(v.DlUserId, infoModel.Date).Unwrap().(agentincome.AgentIncomeModel)
			//修改
			v.CompleteCount -= 1
			v.CancelCount += 1
			v.TotalMoney = agentIncomeInfo.TotalMoney - v.DlMoney
			v.TradeTotal = agentIncomeInfo.TradeTotal - v.SettlementMoney
			v.DivindsMoney = agentIncomeInfo.TotalMoney - v.DlMoney

			if v.CompleteCount < 0 {
				v.BrCompleteCount = 0
			}
			dao.NewOrderDao().UpdateAgentStatistical(&v).Unwrap()
		}

	}

}

func (logic *OrderLogic) ByMoneyAgainStatistical(tradeNo string) {

	infoModel := dao.NewOrderDao().GetPlaceIdAndUserId(tradeNo).Unwrap().(placeresp.PlaceIdAndUserId)

	//查询统计
	placeIncomeInfo := dao.NewOrderDao().GetPlaceIncomeByPlaceId(infoModel.PlaceId, infoModel.Date).Unwrap().(placeincome.PlaceIncomeModel)
	fmt.Println(infoModel)
	//修改网点用户统计
	//infoModel.CompleteCount -= 1
	//infoModel.CancelCount += 1
	infoModel.Income = placeIncomeInfo.Income - infoModel.DlMoney
	infoModel.SettlementMoney = placeIncomeInfo.SettlementMoney - infoModel.SettlementMoney

	//if infoModel.CompleteCount < 0 {
	//	infoModel.BrCompleteCount = 0
	//}

	dao.NewOrderDao().UpdatePlaceStatistical(&infoModel).Unwrap()

	//修改代理商统计
	agentInfo := dao.NewOrderDao().GetAgentStatisticalByTradeNo(tradeNo).Unwrap().([]placeresp.PlaceIdAndUserId)
	for _, v := range agentInfo {
		//分公司
		if v.BrCompleteCount > 0 {
			updateBranchIncome := &placeresp.BranchIncomeStatistical{}
			branchIncomeInfo := dao.NewOrderDao().GetBranchIncomeByPlaceId(v.DlUserId, infoModel.Date).Unwrap().(agentincome.AgentIncomeModel)
			//修改
			//v.BrCompleteCount -= 1
			//v.BrCancelCount += 1
			v.TotalMoney = branchIncomeInfo.TotalMoney - v.DlMoney
			v.TradeTotal = branchIncomeInfo.TradeTotal - v.SettlementMoney

			//if v.BrCompleteCount < 0 {
			//	v.BrCompleteCount = 0
			//}
			updateBranchIncome.UserId = v.DlUserId
			updateBranchIncome.Date = v.Date
			updateBranchIncome.CompleteCount = v.BrCompleteCount
			updateBranchIncome.CancelCount = v.BrCancelCount
			updateBranchIncome.TotalMoney = v.TotalMoney
			updateBranchIncome.TradeTotal = v.TradeTotal
			updateBranchIncome.DivindsMoney = v.TotalMoney
			dao.NewOrderDao().UpdateBranchStatistical(updateBranchIncome).Unwrap()
		}
		//代理商
		if v.CompleteCount > 0 {
			agentIncomeInfo := dao.NewOrderDao().GetAgentIncomeByPlaceId(v.DlUserId, infoModel.Date).Unwrap().(agentincome.AgentIncomeModel)
			//修改
			//v.CompleteCount -= 1
			//v.CancelCount += 1
			v.TotalMoney = agentIncomeInfo.TotalMoney - v.DlMoney
			v.TradeTotal = agentIncomeInfo.TradeTotal - v.SettlementMoney
			v.DivindsMoney = agentIncomeInfo.TotalMoney - v.DlMoney

			//if v.CompleteCount < 0 {
			//	v.BrCompleteCount = 0
			//}
			dao.NewOrderDao().UpdateAgentStatistical(&v).Unwrap()
		}

	}

}

// 国曼提现到零钱-单独用
func (logic *OrderLogic) HandlePlaceTransfersByGM(param *request.WithDrawalReq) error {
	dec, _ := decimal.NewFromString(param.Amount)
	amount := dec.IntPart()

	userData := dao.NewUserDao().GetUserInfoById(param.UserId)
	userInfo := userData.Unwrap().(*users.UserModel)
	if userData.Err != nil || userInfo.ID == 0 {
		logs.Error("GetUserInfoById", userData)
		return userData.Err
	}

	// 取商户提现配置
	pSetting := dao.NewCashDao().GetWithdrawalSettingInfo(2).Unwrap().(withdrawalsetting.WithdrawalSetting)
	cashMoney := logic.GetCashMoney(param.UserId) // 可提现金额
	pSetting.TaxPoint = int(userInfo.TaxRate)
	logs.Info("取商户提现配置", pSetting)

	// 金额验证
	if amount <= 0 {
		return errors.New("金额不能为空")
	}
	if amount < pSetting.MinMoney || amount > pSetting.MaxMoney {
		return errors.New("提现金额不正确")
	}
	log.Println("打印测试可提现金额--", cashMoney, "发起可提现金额", amount)
	if amount > cashMoney {
		return errors.New("提现金额不能大于可提现金额")
	}

	// 获取redis中当天的提现次数 - 对比
	keyCount := utils.Join("count-", param.Openid, "-", time.Now().Format("20060102"))
	count, _ := global.Rdb.Get(context.Background(), keyCount).Int()
	log.Println("打印测试当天的提现次数", count)
	if count > pSetting.DayNumber {
		return errors.New("当天提现次数超过10次")
	}

	// 获取redis中当天的提现金额 - 对比
	keyMoney := utils.Join("money-", param.Openid, "-", time.Now().Format("20060102"))
	money, _ := global.Rdb.Get(context.Background(), keyMoney).Int64()
	log.Println("打印测试当天的提现金额", money)
	if money > pSetting.DayMaxMoney {
		return errors.New("已超出当天限额")
	}
	//dec, _ := decimal.NewFromString(param.Amount)
	//amount := dec.Mul(decimal.NewFromInt(100)).IntPart()
	//var minAmount int64 = 10                     // 提现最小最小金额
	//var maxAmount int64 = 3000                    // 提现最大金额
	//var cashCountToday int = 10                   // 当天的最大提现次数
	//var cashMoneyToday int64 = 300000             // 当天的最大提现金额
	//cashMoney := logic.GetCashMoney(param.UserId) // 可提现金额
	//
	////isCheckName := 0 // 是否验证真实姓名
	////isCashMoney := 0 // 是否收提现手续费
	////isAdminVerify := 0 //是否需要后台审核
	////if isCashMoney == 1 {
	////	amount = amount - amount*per/100 // 提现金额 - 提现金额*手续费百分比/100
	////}
	//
	//log.Println(amount)
	//log.Println(minAmount)
	//if amount < minAmount || amount > maxAmount { // 提现金额不正确
	//	return errors.New("提现金额不正确")
	//}
	//
	//// 提现金额不能大于可提现金额
	//if amount > cashMoney {
	//	return errors.New("提现金额不能大于可提现金额")
	//}
	//
	//// 获取redis中当天的提现次数 - 对比
	//keyCount := utils.Join("count-", param.Openid, "-", time.Now().Format("20060102"))
	//count, _ := global.Rdb.Get(context.Background(), keyCount).Int()
	//log.Println("打印测试当天的提现次数", count)
	//if count > cashCountToday {
	//	return errors.New("当天提现次数超过10次")
	//}
	//
	//// 获取redis中当天的提现金额 - 对比
	//keyMoney := utils.Join("money-", param.Openid, "-", time.Now().Format("20060102"))
	//money, _ := global.Rdb.Get(context.Background(), keyMoney).Int64()
	//log.Println("打印测试当天的提现金额", money)
	//if money > cashMoneyToday {
	//	return errors.New("已超出当天限额")
	//}

	transfersNo := utils.Join(global.Const.Pre.TransferPre, time.Now().Format("20060102150405"), utils.GetRandomInt(6)) // 退款订单号

	apiData := logic.HandleTransfersApiParamV2(transfersNo, param.Openid, param.Desc, param.ClientIp, amount)
	logic.PayClient = wxpay.NewCertCompanyPayClient()
	respData, err := wxpay.ApiTransferByGM(logic.PayClient, apiData) // 请求提现接口
	if err != nil {                                                  // 返回状态码不为200时
		return err
	}
	//log.Println("提现返回值 ", respData)

	// 查询提现 是否成功
	apiQueryData := logic.HandleQueryTransfersApiParamV2(transfersNo)
	respQueryData, err := wxpay.ApiQueryTransferByGM(logic.PayClient, apiQueryData)
	if err != nil { // 返回状态码不为200时
		return err
	}
	log.Println("查询 提现返回值 ", respQueryData)

	var state uint8
	// 转帐状态  SUCCESS:转账成功 FAILED:转账失败 PROCESSING:处理中
	switch respQueryData.Get("status") {
	case "SUCCESS":
		state = 2
	case "FAILED":
		state = 3
	case "PROCESSING":
		state = 1
	}
	//respQueryData.Get("mch_id ") // 商户号

	// 不管成功失败都记录提现日志
	m := cashlog.New()
	m.Appid = respQueryData.Get("appid")                // Appid
	m.TradeNo = respQueryData.Get("partner_trade_no")   // 商户订单号
	m.OutTradeNo = respQueryData.Get("detail_id")       // 付款单号
	m.State = state                                     // 转账状态
	m.OperateNote = respQueryData.Get("reason")         // 失败原因
	m.ReceivingAccount = respQueryData.Get("openid")    // 收款用户openid
	m.TransferName = respQueryData.Get("transfer_name") // 收款用户姓名
	transferMoney, _ := strconv.ParseInt(respQueryData.Get("payment_amount"), 10, 64)
	m.TransferMoney = transferMoney // 付款金额
	m.TransferMoneyStr = utils.Fen2Yuan(transferMoney)

	if respQueryData.Get("transfer_time") == "" {
		m.OperateAt = dingo.Time(0) // 转账时间
	} else {
		m.OperateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))) // 转账时间
	}

	if respQueryData.Get("payment_time") == "" {
		m.CreateAt = dingo.Time(0) // 付款成功时间
	} else {
		m.CreateAt = dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))) // 付款成功时间
	}

	m.ReceivingType = 1                // 收款类型 1 转到零钱 2 银行卡 3 二维码
	m.Desc = respQueryData.Get("desc") // 企业付款备注
	m.UserID = param.UserId
	m.ServiceCharge = 0
	m.VerifyStatus = 2
	m.Money = amount
	m.MoneyStr = utils.Fen2Yuan(amount)

	if respData != nil &&
		respData.Get("return_code") == "SUCCESS" &&
		respData.Get("result_code") == "SUCCESS" {
		m.OperateNote = "系统自动转账成功"
		userInfo := dao.NewUserDao().GetUserInfoByUserId(param.UserId).Unwrap().(users.UserInfoPlaceId)
		receivingInfo := fmt.Sprintf("商户(%s)于%s提现%s元",
			userInfo.PlaceName, respQueryData.Get("payment_time"), utils.Fen2Yuan(transferMoney))
		tm := &cashlog.TransferOrder{
			TradeNo:       respQueryData.Get("partner_trade_no"),
			OutTradeNo:    respQueryData.Get("detail_id"),
			UserID:        param.UserId,
			BusinessType:  1,
			TransferType:  1,
			Money:         transferMoney,
			Note:          respQueryData.Get("desc"),
			State:         int(state),
			ReceivingInfo: receivingInfo,
			ReceivingType: 1,
			WxAppID:       respQueryData.Get("appid"),
			WxOpenID:      respQueryData.Get("openid"),
			PayeeID:       respQueryData.Get("openid"),
			PayeeType:     1,
			UpdateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("payment_time"))),
			CreateAt:      dingo.Time(wechatpay.StrTimeToInt(respQueryData.Get("transfer_time"))),
		}
		// 转帐成功表
		dao.NewCashDao().InsertTransferOrder(tm).Unwrap()
		money = money + amount
		global.Rdb.Set(context.Background(), keyMoney, money, time.Hour*24)
	}
	dao.NewCashDao().InsertCashLog(m).Unwrap() // 转帐日志
	count = count + 1
	global.Rdb.Set(context.Background(), keyCount, count, time.Hour*24) // 记录当天提现次数
	return nil
}

// 开始计费时长更新
func (logic *OrderLogic) HandleUpdateAwardTimeOrder(param *request.WxUpdateAwardTime) error {
	return dao.NewOrderDao().UpdateBeginAtOrder(param.OrderId, param.Second).Err
}

func (logic *OrderLogic) HandleOrderDividendsByTradeNo(tradeNo string) error {
	orderInfo := dao.NewOrderDao().OrderInfoByTradeNo(tradeNo).Unwrap().(*orders.OrderModel)
	//查询订单对应的设备信息
	deviceInfo := dao.NewOrderDao().GetDeviceInfo(orderInfo.DeviceSn).Unwrap().(*devices.DeviceType)

	userInfo := dao.NewUserDao().GetUserInfoByPlaceId(orderInfo.PlaceId).Unwrap().(*users.UserModel)

	//查询订单是否分红
	count := dao.NewOrderDao().CountDividendsLogsByTradeNo(orderInfo.TradeNo, userInfo.ID).Unwrap().(int64)

	if count != 0 {
		log.Println("该订单已分红")
		err := errors.New("该订单已分红")
		return err
	}

	dingo.Task(NewOrderLogic().CalOrderDividends, func() {}, orderInfo, deviceInfo, orderInfo.SettlementMoney, int64(orderInfo.EndAt)) // 计算分红 - 异步任务
	return nil
}

//
func (logic *OrderLogic) RefreshComplaintsLog(totalCount int, urlStr string) error {
	var offset, limit int
	pageUrl := "limit=%d&offset=%d&"
	urlStr += pageUrl
	wc := NewSettingLogic().GetPaySetting()
	for i := 1; i <= 10; i++ {

		if totalCount == 0 {
			break
		}

		if totalCount > 10 {
			limit += 10
			offset = limit - 10
			totalCount -= 10
			url := fmt.Sprintf(urlStr, limit, offset)
			resMap, err := wechatpay.ApiGetComplaintsList(url, wc)
			if err != nil {

				return err
			}

			data := resMap["data"].([]interface{})
			var BeijingLocation = time.FixedZone("Asia/Shanghai", 8*60*60)
			for _, v := range data {
				complaints := &complaintslog.TransitionComplaintsLog{}
				mapData := v.(map[string]interface{})

				if mapData["payer_phone"] != nil {
					cipherText := mapData["payer_phone"].(string)
					mapData["payer_phone"] = wechatpay.DecryptOAEP(cipherText, wc.ApiclientKeyPath)
				}

				layout := "2006-01-02T15:04:05+08:00"
				successTime, _ := time.ParseInLocation(layout, mapData["complaint_time"].(string), BeijingLocation)
				//successTime.AddDate(0, 0, -1)
				mapData["complaint_time"] = successTime.Format("2006-01-02 15:04:05")

				var stateStr string
				state := mapData["complaint_state"].(string)

				switch state {
				case "PENDING":
					stateStr = "待处理"
				case "PROCESSING":
					stateStr = "处理中"
				case "PROCESSED":
					stateStr = "已处理完成"
				}

				mapData["complaint_state"] = stateStr

				//投诉单关联订单信息转为string存储
				orderInfo := mapData["complaint_order_info"].([]interface{})
				orderInfoByte, _ := json.Marshal(orderInfo)
				//fmt.Println(string(orderInfoByte))
				complaints.ComplaintOrderInfo = string(orderInfoByte)
				//投诉资料列表
				mediaList := mapData["complaint_media_list"].([]interface{})
				mediaListByte, _ := json.Marshal(mediaList)
				//fmt.Println(string(mediaListByte))
				complaints.ComplaintMediaList = string(mediaListByte)

				if mapData["complaint_full_refunded"].(bool) {
					complaints.ComplaintFullRefunded = 1
				} else {
					complaints.ComplaintFullRefunded = 2
				}

				if mapData["incoming_user_response"].(bool) {
					complaints.IncomingUserResponse = 1
				} else {
					complaints.IncomingUserResponse = 2
				}

				mapByte, _ := json.Marshal(mapData)
				_ = json.Unmarshal(mapByte, &complaints)

				//查询是否入库过
				isCreate := dao.NewOrderDao().GetComplaintsIsCreate(mapData["complaint_id"].(string)).Unwrap().(int64)
				if isCreate > 0 {
					complaints.UpdateAt = time.Now().Format("2006-01-02 15:04:05")
					data := dao.NewOrderDao().UpdateComplaintsLog(complaints)
					if data.Err != nil {
						log.Println("修改投诉单日志失败！", data.Err)
					}

				} else {
					complaints.CreateAt = time.Now().Format("2006-01-02 15:04:05")
					complaints.UpdateAt = time.Now().Format("2006-01-02 15:04:05")
					data := dao.NewOrderDao().CreateComplaintsLog(complaints)
					if data.Err != nil {
						log.Println("新增投诉单日志失败！", data.Err)
					}

				}

			}
		} else {

			limit += int(totalCount)
			totalCount = 0
			url := fmt.Sprintf(urlStr, limit, offset)
			resMap, err := wechatpay.ApiGetComplaintsList(url, wc)
			if err != nil {

				return err
			}

			data := resMap["data"].([]interface{})
			var BeijingLocation = time.FixedZone("Asia/Shanghai", 8*60*60)
			for _, v := range data {
				complaints := &complaintslog.TransitionComplaintsLog{}
				mapData := v.(map[string]interface{})

				if mapData["payer_phone"] != nil {
					cipherText := mapData["payer_phone"].(string)
					mapData["payer_phone"] = wechatpay.DecryptOAEP(cipherText, wc.ApiclientKeyPath)
				}

				layout := "2006-01-02T15:04:05+08:00"
				successTime, _ := time.ParseInLocation(layout, mapData["complaint_time"].(string), BeijingLocation)
				//successTime.AddDate(0, 0, -1)
				mapData["complaint_time"] = successTime.Format("2006-01-02 15:04:05")

				var stateStr string
				state := mapData["complaint_state"].(string)

				switch state {
				case "PENDING":
					stateStr = "待处理"
				case "PROCESSING":
					stateStr = "处理中"
				case "PROCESSED":
					stateStr = "已处理完成"
				}

				mapData["complaint_state"] = stateStr

				//投诉单关联订单信息转为string存储
				orderInfo := mapData["complaint_order_info"].([]interface{})
				orderInfoByte, _ := json.Marshal(orderInfo)
				//fmt.Println(string(orderInfoByte))
				complaints.ComplaintOrderInfo = string(orderInfoByte)
				//投诉资料列表
				mediaList := mapData["complaint_media_list"].([]interface{})
				mediaListByte, _ := json.Marshal(mediaList)
				//fmt.Println(string(mediaListByte))
				complaints.ComplaintMediaList = string(mediaListByte)

				if mapData["complaint_full_refunded"].(bool) {
					complaints.ComplaintFullRefunded = 1
				} else {
					complaints.ComplaintFullRefunded = 2
				}

				if mapData["incoming_user_response"].(bool) {
					complaints.IncomingUserResponse = 1
				} else {
					complaints.IncomingUserResponse = 2
				}

				mapByte, _ := json.Marshal(mapData)
				_ = json.Unmarshal(mapByte, &complaints)

				//查询是否入库过
				isCreate := dao.NewOrderDao().GetComplaintsIsCreate(mapData["complaint_id"].(string)).Unwrap().(int64)
				if isCreate > 0 {
					complaints.UpdateAt = time.Now().Format("2006-01-02 15:04:05")
					data := dao.NewOrderDao().UpdateComplaintsLog(complaints)
					if data.Err != nil {
						log.Println("修改投诉单日志失败！", data.Err)
					}

				} else {
					complaints.CreateAt = time.Now().Format("2006-01-02 15:04:05")
					complaints.UpdateAt = time.Now().Format("2006-01-02 15:04:05")
					data := dao.NewOrderDao().CreateComplaintsLog(complaints)
					if data.Err != nil {
						log.Println("新增投诉单日志失败！", data.Err)
					}

				}

			}

			break
		}
	}
	return nil
}
